"use client";
import { useState } from "react";
import { Button } from "@/components/ui/button";
import { Field, SelectField, TextareaField } from "@/components/shared/field";
import { Editor } from "./editor";
import type {
  CreateAssignmentPayload,
  CreateTariffPayload,
  PricingCatalog,
  TariffPriceComponent,
  TariffPriceComponentType,
  TariffSummary,
} from "./api-contract";
import {
  TARIFF_PRICE_COMPONENT_TYPES,
  TARIFF_PRICE_COMPONENT_UNITS,
} from "./api-contract";

type ComponentDraft = TariffPriceComponent & { key: string };
type TariffDraft = Omit<CreateTariffPayload, "price_components"> & {
  price_components: ComponentDraft[];
};

const componentDefaults: Record<
  TariffPriceComponentType,
  Pick<TariffPriceComponent, "name" | "unit">
> = {
  SERVICE: { name: "Service fee", unit: "minute" },
  ENERGY: { name: "Energy fee", unit: "kWh" },
  PARKING_TIME: { name: "Parking time fee", unit: "minute" },
  IDLE: { name: "Idle fee", unit: "minute" },
  MAINTENANCE: { name: "Maintenance fee", unit: "minute" },
  APPLICATION: { name: "Application fee", unit: "minute" },
};

function newComponent(type: TariffPriceComponentType = "ENERGY"): ComponentDraft {
  return {
    key: crypto.randomUUID(),
    type,
    ...componentDefaults[type],
    price: 0,
    tax: 0,
    active: true,
  };
}

function newTariffDraft(commercialModels: readonly string[]): TariffDraft {
  return {
    code: "",
    name: "",
    description: "",
    commercial_model: commercialModels[0] ?? "B2C",
    currency: "IDR",
    minimum_amount: 0,
    active: true,
    price_components: [newComponent()],
  };
}

export function CreateTariffDialog({
  commercialModels,
  error,
  submitting,
  onClose,
  onSubmit,
}: {
  commercialModels: readonly string[];
  error: string;
  submitting: boolean;
  onClose: () => void;
  onSubmit: (payload: CreateTariffPayload) => void;
}) {
  const models = commercialModels.length ? commercialModels : ["B2C"];
  const [draft, setDraft] = useState(() => newTariffDraft(models));
  const updateComponent = (
    index: number,
    change: Partial<ComponentDraft>,
  ) =>
    setDraft((current) => ({
      ...current,
      price_components: current.price_components.map((component, row) =>
        row === index ? { ...component, ...change } : component,
      ),
    }));
  const updateComponentType = (index: number, type: TariffPriceComponentType) =>
    setDraft((current) => ({
      ...current,
      price_components: current.price_components.map((component, row) => {
        if (row !== index) return component;
        const previousDefaults = componentDefaults[component.type];
        const nextDefaults = componentDefaults[type];
        return {
          ...component,
          type,
          name:
            component.name === previousDefaults.name
              ? nextDefaults.name
              : component.name,
          unit:
            component.unit === previousDefaults.unit
              ? nextDefaults.unit
              : component.unit,
        };
      }),
    }));

  return (
    <Editor
      open
      title="Create charging tariff"
      description="Set the commercial terms and the price components saved with this tariff."
      submitLabel="Create tariff"
      submitting={submitting}
      error={error}
      onClose={onClose}
      onSubmit={() => {
        const { price_components, ...fields } = draft;
        onSubmit({
          ...fields,
          price_components: price_components.map((component) => ({
            type: component.type,
            name: component.name,
            unit: component.unit,
            price: component.price,
            ...(component.cost_price !== undefined
              ? { cost_price: component.cost_price }
              : {}),
            tax: component.tax,
            ...(component.grace_period !== undefined
              ? { grace_period: component.grace_period }
              : {}),
            active: component.active,
          })),
        });
      }}
    >
      <div className="grid gap-4 sm:grid-cols-2">
        <Field
          label="Tariff code"
          required
          maxLength={255}
          value={draft.code}
          onChange={(event) => setDraft({ ...draft, code: event.target.value })}
        />
        <Field
          label="Tariff name"
          required
          maxLength={255}
          value={draft.name}
          onChange={(event) => setDraft({ ...draft, name: event.target.value })}
        />
        <SelectField
          label="Commercial model"
          options={models}
          value={draft.commercial_model}
          onChange={(event) =>
            setDraft({ ...draft, commercial_model: event.target.value })
          }
        />
        <SelectField
          label="Currency"
          options={["IDR", "USD", "EUR", "SGD", "GBP", "JPY", "MYR", "THB"]}
          value={draft.currency}
          onChange={(event) => setDraft({ ...draft, currency: event.target.value })}
        />
          <Field
            label="Minimum amount"
            type="number"
            min="0"
            step="0.01"
            required
            value={Number.isFinite(draft.minimum_amount) ? draft.minimum_amount : ""}
            onChange={(event) =>
              setDraft({ ...draft, minimum_amount: event.target.valueAsNumber })
            }
          />
        <SelectField
          label="Status"
          options={["Active", "Inactive"]}
          value={draft.active ? "Active" : "Inactive"}
          onChange={(event) =>
            setDraft({ ...draft, active: event.target.value === "Active" })
          }
        />
      </div>
      <TextareaField
        label="Description"
        maxLength={1000}
        value={draft.description}
        onChange={(event) =>
          setDraft({ ...draft, description: event.target.value })
        }
      />
      <section className="space-y-3 border-t pt-4">
        <div className="flex flex-wrap items-center justify-between gap-3">
          <div>
            <h3 className="font-semibold">Price components</h3>
            <p className="text-xs text-muted-foreground">
              Each component is stored inside the tariff.
            </p>
          </div>
          <Button
            type="button"
            size="sm"
            variant="outline"
            onClick={() =>
              setDraft((current) => ({
                ...current,
                price_components: [...current.price_components, newComponent()],
              }))
            }
          >
            Add component
          </Button>
        </div>
        {draft.price_components.map((component, index) => (
          <fieldset className="rounded-lg border bg-muted/20 p-4" key={component.key}>
            <legend className="px-1 text-xs font-medium text-muted-foreground">
              Component {index + 1}
            </legend>
            <div className="grid gap-3 sm:grid-cols-2">
              <SelectField
                label="Type"
                options={TARIFF_PRICE_COMPONENT_TYPES}
                value={component.type}
                onChange={(event) =>
                  updateComponentType(index, event.target.value as TariffPriceComponentType)
                }
              />
              <Field
                label="Component name"
                required
                value={component.name}
                onChange={(event) => updateComponent(index, { name: event.target.value })}
              />
              <SelectField
                label="Unit"
                required
                options={TARIFF_PRICE_COMPONENT_UNITS}
                value={component.unit}
                onChange={(event) => updateComponent(index, { unit: event.target.value })}
              />
              <Field
                label="Price"
                type="number"
                min="0"
                step="0.01"
                required
                value={Number.isFinite(component.price) ? component.price : ""}
                onChange={(event) => updateComponent(index, { price: event.target.valueAsNumber })}
              />
              <Field
                label="Cost price (optional)"
                type="number"
                min="0"
                step="0.01"
                value={component.cost_price ?? ""}
                onChange={(event) =>
                  updateComponent(index, {
                    cost_price:
                      event.target.value === "" ? undefined : event.target.valueAsNumber,
                  })
                }
              />
              <Field
                label="Tax (%)"
                type="number"
                min="0"
                step="0.01"
                required
                value={Number.isFinite(component.tax) ? component.tax : ""}
                onChange={(event) => updateComponent(index, { tax: event.target.valueAsNumber })}
              />
              <Field
                label="Grace period (optional)"
                type="number"
                min="0"
                step="1"
                value={component.grace_period ?? ""}
                onChange={(event) =>
                  updateComponent(index, {
                    grace_period:
                      event.target.value === "" ? undefined : event.target.valueAsNumber,
                  })
                }
              />
              <SelectField
                label="Status"
                options={["Active", "Inactive"]}
                value={component.active ? "Active" : "Inactive"}
                onChange={(event) =>
                  updateComponent(index, { active: event.target.value === "Active" })
                }
              />
            </div>
            {draft.price_components.length > 1 && (
              <Button
                className="mt-3"
                type="button"
                size="sm"
                variant="ghost"
                onClick={() =>
                  setDraft((current) => ({
                    ...current,
                    price_components: current.price_components.filter(
                      (_, row) => row !== index,
                    ),
                  }))
                }
              >
                Remove component
              </Button>
            )}
          </fieldset>
        ))}
      </section>
    </Editor>
  );
}

export function AssignTariffDialog({
  tariff,
  catalog,
  error,
  submitting,
  onClose,
  onSubmit,
}: {
  tariff: TariffSummary;
  catalog: PricingCatalog;
  error: string;
  submitting: boolean;
  onClose: () => void;
  onSubmit: (payload: CreateAssignmentPayload) => void;
}) {
  const availableSchedules = catalog.schedules.data.filter(
    (item) => item.active && item.commercial_model === tariff.commercial_model,
  );
  const [locationId, setLocationId] = useState("");
  const [chargepointId, setChargepointId] = useState("");
  const [connectorId, setConnectorId] = useState("");
  const [scheduleId, setScheduleId] = useState("");
  const [provider, setProvider] = useState("");
  const [priority, setPriority] = useState(Number.NaN);
  const [assignmentStatus, setAssignmentStatus] = useState<"Active" | "Inactive" | "">("");
  const [validationError, setValidationError] = useState("");
  const chargepoints = catalog.chargepoints.data.filter(
    (item) => item.active && item.location_id === locationId,
  );
  const nozzles = catalog.nozzles.data.filter(
    (item) => item.active && item.chargepoint_id === chargepointId,
  );
  const selectedNozzle = nozzles.find((item) => item.id === connectorId);

  const submit = () => {
    if (!locationId || !chargepointId || !selectedNozzle || !scheduleId) {
      setValidationError("Choose a location, chargepoint, connector and active tariff schedule.");
      return;
    }
    if (!provider.trim()) {
      setValidationError("Enter an electricity provider.");
      return;
    }
    if (!Number.isInteger(priority) || priority < 0) {
      setValidationError("Priority must be a whole number of zero or more.");
      return;
    }
    if (!assignmentStatus) {
      setValidationError("Choose an assignment status.");
      return;
    }
    setValidationError("");
    onSubmit({
      location_id: locationId,
      chargepoint_id: chargepointId,
      connector_id: selectedNozzle.id,
      connector_number: selectedNozzle.connector_number,
      commercial_model: tariff.commercial_model,
      tariff_schedule_id: scheduleId,
      electricity_provider: provider.trim(),
      priority,
      active: assignmentStatus === "Active",
    });
  };

  return (
    <Editor
      open
      title={`Assign ${tariff.name}`}
      description="Choose a charging location, device and connector for this tariff."
      submitLabel="Create assignment"
      submitting={submitting}
      error={validationError || error}
      onClose={onClose}
      onSubmit={submit}
    >
      <div className="grid gap-4 sm:grid-cols-2">
        <SelectField
          label="Location"
          required
          options={[
            { value: "", label: "Select a location" },
            ...catalog.locations.data
              .filter((item) => item.active)
              .map((item) => ({ value: item.id, label: `${item.name} · ${item.code}` })),
          ]}
          value={locationId}
          onChange={(event) => {
            setValidationError("");
            setLocationId(event.target.value);
            setChargepointId("");
            setConnectorId("");
          }}
        />
        <SelectField
          label="Chargepoint"
          required
          options={[
            { value: "", label: "Select a chargepoint" },
            ...chargepoints.map((item) => ({ value: item.id, label: `${item.name} · ${item.status}` })),
          ]}
          value={chargepointId}
          onChange={(event) => {
            setValidationError("");
            setChargepointId(event.target.value);
            setConnectorId("");
          }}
          disabled={!locationId || chargepoints.length === 0}
        />
        <SelectField
          label="Connector"
          required
          options={[
            { value: "", label: "Select a connector" },
            ...nozzles.map((item) => ({
              value: item.id,
              label: `Connector ${item.connector_number} · ${item.name}`,
            })),
          ]}
          value={connectorId}
          onChange={(event) => { setValidationError(""); setConnectorId(event.target.value); }}
          disabled={!chargepointId || nozzles.length === 0}
        />
        <SelectField
          label="Tariff schedule"
          required
          options={[
            { value: "", label: "Select a schedule" },
            ...availableSchedules.map((item) => ({ value: item.id, label: item.name })),
          ]}
          value={scheduleId}
          onChange={(event) => { setValidationError(""); setScheduleId(event.target.value); }}
          disabled={availableSchedules.length === 0}
        />
        <Field
          label="Electricity provider"
          required
          maxLength={255}
          value={provider}
          onChange={(event) => { setValidationError(""); setProvider(event.target.value); }}
        />
        <Field
          label="Priority"
          type="number"
          min="0"
          step="1"
          required
          value={Number.isFinite(priority) ? priority : ""}
          onChange={(event) => { setValidationError(""); setPriority(event.target.valueAsNumber); }}
        />
        <SelectField
          label="Status"
          required
          options={[
            { value: "", label: "Select a status" },
            "Active",
            "Inactive",
          ]}
          value={assignmentStatus}
          onChange={(event) => {
            setValidationError("");
            setAssignmentStatus(event.target.value as "Active" | "Inactive" | "");
          }}
        />
      </div>
      {locationId && chargepoints.length === 0 && !catalog.chargepoints.error && (
        <p role="status" className="rounded-md border bg-muted/40 p-3 text-sm text-muted-foreground">
          No active chargepoints are available at this location. Choose another location.
        </p>
      )}
      {chargepointId && nozzles.length === 0 && !catalog.nozzles.error && (
        <p role="status" className="rounded-md border bg-muted/40 p-3 text-sm text-muted-foreground">
          No active connectors are available on this chargepoint. Choose another chargepoint.
        </p>
      )}
      {(catalog.locations.error || catalog.chargepoints.error || catalog.nozzles.error) && (
        <p role="alert" className="rounded-md border border-destructive/30 bg-destructive/5 p-3 text-sm text-destructive">
          Charger assignment options could not be loaded. Refresh the page and try again.
        </p>
      )}
      {availableSchedules.length === 0 && (
        <p className="rounded-md border bg-muted/40 p-3 text-sm text-muted-foreground">
          Create an active {tariff.commercial_model} schedule before assigning this tariff.
        </p>
      )}
    </Editor>
  );
}
