import type { ShipmentInput, ShipmentOrderOptionDto } from "@mrp/shared/dist/shipping/types.js";
import { useEffect, useState } from "react";
import { useNavigate, useParams, useSearchParams } from "react-router-dom";

import { useAuth } from "../../auth/AuthProvider";
import { api, ApiError } from "../../lib/api";
import { emptyShipmentInput, shipmentStatusOptions } from "./config";

export function ShipmentFormPage({ mode }: { mode: "create" | "edit" }) {
  const { token } = useAuth();
  const navigate = useNavigate();
  const { shipmentId } = useParams();
  const [searchParams] = useSearchParams();
  const seededOrderId = searchParams.get("orderId") ?? "";
  const [form, setForm] = useState<ShipmentInput>({ ...emptyShipmentInput, salesOrderId: seededOrderId });
  const [orderOptions, setOrderOptions] = useState<ShipmentOrderOptionDto[]>([]);
  const [orderSearchTerm, setOrderSearchTerm] = useState("");
  const [orderPickerOpen, setOrderPickerOpen] = useState(false);
  const [status, setStatus] = useState(mode === "create" ? "Create a new shipment." : "Loading shipment...");
  const [isSaving, setIsSaving] = useState(false);

  useEffect(() => {
    if (!token) {
      return;
    }

    api.getShipmentOrderOptions(token).then((options) => {
      setOrderOptions(options);
      const seeded = options.find((option) => option.id === seededOrderId);
      if (seeded && mode === "create") {
        setOrderSearchTerm(`${seeded.documentNumber} - ${seeded.customerName}`);
      }
    }).catch(() => setOrderOptions([]));
  }, [mode, seededOrderId, token]);

  useEffect(() => {
    if (!token || mode !== "edit" || !shipmentId) {
      return;
    }

    api.getShipment(token, shipmentId)
      .then((shipment) => {
        setForm({
          salesOrderId: shipment.salesOrderId,
          status: shipment.status,
          shipDate: shipment.shipDate,
          carrier: shipment.carrier,
          serviceLevel: shipment.serviceLevel,
          trackingNumber: shipment.trackingNumber,
          packageCount: shipment.packageCount,
          notes: shipment.notes,
        });
        setOrderSearchTerm(`${shipment.salesOrderNumber} - ${shipment.customerName}`);
        setStatus("Shipment loaded.");
      })
      .catch((error: unknown) => {
        const message = error instanceof ApiError ? error.message : "Unable to load shipment.";
        setStatus(message);
      });
  }, [mode, shipmentId, token]);

  function updateField<Key extends keyof ShipmentInput>(key: Key, value: ShipmentInput[Key]) {
    setForm((current) => ({ ...current, [key]: value }));
  }

  function getSelectedOrder(orderId: string) {
    return orderOptions.find((option) => option.id === orderId) ?? null;
  }

  async function handleSubmit(event: React.FormEvent<HTMLFormElement>) {
    event.preventDefault();
    if (!token) {
      return;
    }

    setIsSaving(true);
    setStatus("Saving shipment...");
    try {
      const saved = mode === "create" ? await api.createShipment(token, form) : await api.updateShipment(token, shipmentId ?? "", form);
      navigate(`/shipping/shipments/${saved.id}`);
    } catch (error: unknown) {
      const message = error instanceof ApiError ? error.message : "Unable to save shipment.";
      setStatus(message);
      setIsSaving(false);
    }
  }

  function closeEditor() {
    navigate(mode === "create" ? "/shipping/shipments" : `/shipping/shipments/${shipmentId}`);
  }

  return (
    <form className="page-stack" onSubmit={handleSubmit}>
      <section className="surface-panel">
        <div className="flex flex-col gap-3 lg:flex-row lg:items-start lg:justify-between">
          <div>
            <p className="section-kicker">SHIPPING EDITOR</p>
            <h3 className="module-title">{mode === "create" ? "New Shipment" : "Edit Shipment"}</h3>
          </div>
          <button type="button" onClick={closeEditor} className="inline-flex items-center justify-center rounded-2xl border border-line/70 px-2 py-2 text-sm font-semibold text-text">
            Cancel
          </button>
        </div>
      </section>
      <section className="space-y-3 surface-panel">
        <label className="block">
          <span className="mb-2 block text-sm font-semibold text-text">Sales Order</span>
          <div className="relative">
            <input
              value={orderSearchTerm}
              onChange={(event) => {
                setOrderSearchTerm(event.target.value);
                updateField("salesOrderId", "");
                setOrderPickerOpen(true);
              }}
              onFocus={() => setOrderPickerOpen(true)}
              onBlur={() => {
                window.setTimeout(() => {
                  setOrderPickerOpen(false);
                  const selected = getSelectedOrder(form.salesOrderId);
                  if (selected) {
                    setOrderSearchTerm(`${selected.documentNumber} - ${selected.customerName}`);
                  }
                }, 120);
              }}
              placeholder="Search sales order"
              className="w-full rounded-2xl border border-line/70 bg-page px-2 py-2 text-text outline-none transition focus:border-brand"
            />
            {orderPickerOpen ? (
              <div className="absolute z-20 mt-2 max-h-64 w-full overflow-y-auto rounded-2xl border border-line/70 bg-surface shadow-panel">
                {orderOptions
                  .filter((option) => {
                    const query = orderSearchTerm.trim().toLowerCase();
                    if (!query) {
                      return true;
                    }
                    return option.documentNumber.toLowerCase().includes(query) || option.customerName.toLowerCase().includes(query);
                  })
                  .slice(0, 12)
                  .map((option) => (
                    <button
                      key={option.id}
                      type="button"
                      onMouseDown={(event) => {
                        event.preventDefault();
                        updateField("salesOrderId", option.id);
                        setOrderSearchTerm(`${option.documentNumber} - ${option.customerName}`);
                        setOrderPickerOpen(false);
                      }}
                      className="block w-full border-b border-line/50 px-2 py-2 text-left text-sm transition last:border-b-0 hover:bg-page/70"
                    >
                      <div className="font-semibold text-text">{option.documentNumber}</div>
                      <div className="mt-1 text-xs text-muted">{option.customerName}</div>
                    </button>
                  ))}
              </div>
            ) : null}
          </div>
        </label>
        <div className="grid gap-3 xl:grid-cols-3">
          <label className="block">
            <span className="mb-2 block text-sm font-semibold text-text">Status</span>
            <select value={form.status} onChange={(event) => updateField("status", event.target.value as ShipmentInput["status"])} className="w-full rounded-2xl border border-line/70 bg-page px-2 py-2 text-text outline-none transition focus:border-brand">
              {shipmentStatusOptions.map((option) => (
                <option key={option.value} value={option.value}>{option.label}</option>
              ))}
            </select>
          </label>
          <label className="block">
            <span className="mb-2 block text-sm font-semibold text-text">Ship Date</span>
            <input type="date" value={form.shipDate ? form.shipDate.slice(0, 10) : ""} onChange={(event) => updateField("shipDate", event.target.value ? new Date(event.target.value).toISOString() : null)} className="w-full rounded-2xl border border-line/70 bg-page px-2 py-2 text-text outline-none transition focus:border-brand" />
          </label>
          <label className="block">
            <span className="mb-2 block text-sm font-semibold text-text">Packages</span>
            <input type="number" min={1} step={1} value={form.packageCount} onChange={(event) => updateField("packageCount", Number.parseInt(event.target.value, 10) || 1)} className="w-full rounded-2xl border border-line/70 bg-page px-2 py-2 text-text outline-none transition focus:border-brand" />
          </label>
        </div>
        <div className="grid gap-3 xl:grid-cols-3">
          <label className="block">
            <span className="mb-2 block text-sm font-semibold text-text">Carrier</span>
            <input value={form.carrier} onChange={(event) => updateField("carrier", event.target.value)} className="w-full rounded-2xl border border-line/70 bg-page px-2 py-2 text-text outline-none transition focus:border-brand" />
          </label>
          <label className="block">
            <span className="mb-2 block text-sm font-semibold text-text">Service Level</span>
            <input value={form.serviceLevel} onChange={(event) => updateField("serviceLevel", event.target.value)} className="w-full rounded-2xl border border-line/70 bg-page px-2 py-2 text-text outline-none transition focus:border-brand" />
          </label>
          <label className="block">
            <span className="mb-2 block text-sm font-semibold text-text">Tracking Number</span>
            <input value={form.trackingNumber} onChange={(event) => updateField("trackingNumber", event.target.value)} className="w-full rounded-2xl border border-line/70 bg-page px-2 py-2 text-text outline-none transition focus:border-brand" />
          </label>
        </div>
        <label className="block">
          <span className="mb-2 block text-sm font-semibold text-text">Notes</span>
          <textarea value={form.notes} onChange={(event) => updateField("notes", event.target.value)} rows={4} className="w-full rounded-[18px] border border-line/70 bg-page px-2 py-2 text-text outline-none transition focus:border-brand" />
        </label>
        <div className="flex flex-col gap-3 rounded-2xl border border-line/70 bg-page/70 px-2 py-2 sm:flex-row sm:items-center sm:justify-between">
          <span className="min-w-0 text-sm text-muted">{status}</span>
          <button type="submit" disabled={isSaving} className="rounded-2xl bg-brand px-2 py-2 text-sm font-semibold text-white disabled:cursor-not-allowed disabled:opacity-60">
            {isSaving ? "Saving..." : mode === "create" ? "Create shipment" : "Save changes"}
          </button>
        </div>
      </section>
    </form>
  );
}

