import type { FileAttachmentDto, PurchaseVendorOptionDto } from "@mrp/shared";
import { permissions } from "@mrp/shared";
import type {
  InventoryBomLineInput,
  InventoryItemInput,
  InventoryItemOperationInput,
  InventoryItemOptionDto,
  InventorySkuBuilderPreviewDto,
  InventorySkuFamilyDto,
  InventorySkuNodeDto,
} from "@mrp/shared/dist/inventory/types.js";
import type { ManufacturingStationDto } from "@mrp/shared";
import { useEffect, useState } from "react";
import { useNavigate, useParams } from "react-router-dom";

import { ConfirmActionDialog } from "../../components/ConfirmActionDialog";
import { useAuth } from "../../auth/AuthProvider";
import { api, ApiError } from "../../lib/api";
import { emptyInventoryBomLineInput, emptyInventoryItemInput, emptyInventoryOperationInput, inventoryStatusOptions, inventoryThumbnailOwnerType, inventoryTypeOptions, inventoryUnitOptions } from "./config";

interface InventoryFormPageProps {
  mode: "create" | "edit";
}

export function InventoryFormPage({ mode }: InventoryFormPageProps) {
  const navigate = useNavigate();
  const { token, user } = useAuth();
  const { itemId } = useParams();
  const [form, setForm] = useState<InventoryItemInput>(emptyInventoryItemInput);
  const [componentOptions, setComponentOptions] = useState<InventoryItemOptionDto[]>([]);
  const [stations, setStations] = useState<ManufacturingStationDto[]>([]);
  const [vendorOptions, setVendorOptions] = useState<PurchaseVendorOptionDto[]>([]);
  const [componentSearchTerms, setComponentSearchTerms] = useState<string[]>([]);
  const [activeComponentPicker, setActiveComponentPicker] = useState<number | null>(null);
  const [vendorSearchTerm, setVendorSearchTerm] = useState("");
  const [vendorPickerOpen, setVendorPickerOpen] = useState(false);
  const [status, setStatus] = useState(mode === "create" ? "Create a new inventory item." : "Loading inventory item...");
  const [isSaving, setIsSaving] = useState(false);
  const [pendingRemoval, setPendingRemoval] = useState<{ kind: "operation" | "bom-line"; index: number } | null>(null);
  const [skuFamilies, setSkuFamilies] = useState<InventorySkuFamilyDto[]>([]);
  const [skuLevelOptions, setSkuLevelOptions] = useState<InventorySkuNodeDto[][]>([]);
  const [selectedSkuNodeIds, setSelectedSkuNodeIds] = useState<Array<string | null>>([]);
  const [skuPreview, setSkuPreview] = useState<InventorySkuBuilderPreviewDto | null>(null);
  const [thumbnailAttachment, setThumbnailAttachment] = useState<FileAttachmentDto | null>(null);
  const [thumbnailPreviewUrl, setThumbnailPreviewUrl] = useState<string | null>(null);
  const [pendingThumbnailFile, setPendingThumbnailFile] = useState<File | null>(null);
  const [removeThumbnailOnSave, setRemoveThumbnailOnSave] = useState(false);

  function getComponentOption(componentItemId: string) {
    return componentOptions.find((option) => option.id === componentItemId) ?? null;
  }

  function getComponentSku(componentItemId: string) {
    return getComponentOption(componentItemId)?.sku ?? "";
  }

  function getSkuFamilyName(familyId: string | null) {
    if (!familyId) {
      return "";
    }

    return skuFamilies.find((family) => family.id === familyId)?.name ?? "";
  }

  function replaceThumbnailPreview(nextUrl: string | null) {
    setThumbnailPreviewUrl((current) => {
      if (current) {
        window.URL.revokeObjectURL(current);
      }

      return nextUrl;
    });
  }

  const canReadFiles = user?.permissions.includes(permissions.filesRead) ?? false;
  const canWriteFiles = user?.permissions.includes(permissions.filesWrite) ?? false;

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

    api
      .getInventoryItemOptions(token)
      .then((options) => {
        const nextOptions = options.filter((option) => option.id !== itemId);
        setComponentOptions(nextOptions);
        setComponentSearchTerms((current) =>
          form.bomLines.map((line, index) => {
            if (current[index]?.trim()) {
              return current[index];
            }

            const match = nextOptions.find((option) => option.id === line.componentItemId);
            return match ? match.sku : "";
          })
        );
      })
      .catch(() => setComponentOptions([]));
  }, [form.bomLines, itemId, token]);

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

    api
      .getInventoryItem(token, itemId)
      .then((item) => {
        setForm({
          sku: item.sku,
          skuBuilder: item.skuBuilder ? { familyId: item.skuBuilder.familyId, nodeId: item.skuBuilder.nodeId } : null,
          name: item.name,
          description: item.description,
          type: item.type,
          status: item.status,
          unitOfMeasure: item.unitOfMeasure,
          isSellable: item.isSellable,
          isPurchasable: item.isPurchasable,
          preferredVendorId: item.preferredVendorId,
          defaultCost: item.defaultCost,
          defaultPrice: item.defaultPrice,
          notes: item.notes,
          bomLines: item.bomLines.map((line) => ({
            componentItemId: line.componentItemId,
            quantity: line.quantity,
            unitOfMeasure: line.unitOfMeasure,
            notes: line.notes,
            position: line.position,
          })),
          operations: item.operations.map((operation) => ({
            stationId: operation.stationId,
            setupMinutes: operation.setupMinutes,
            runMinutesPerUnit: operation.runMinutesPerUnit,
            moveMinutes: operation.moveMinutes,
            position: operation.position,
            notes: operation.notes,
          })),
        });
        setSelectedSkuNodeIds(item.skuBuilder?.nodePath.map((entry) => entry.id) ?? []);
        setSkuPreview(item.skuBuilder ? { ...item.skuBuilder, nextSequenceNumber: item.skuBuilder.sequenceNumber ?? 0, availableLevels: Math.max(0, 6 - item.skuBuilder.segments.length), hasChildren: false } : null);
        setComponentSearchTerms(item.bomLines.map((line) => line.componentSku));
        setStatus("Inventory item loaded.");
        setVendorSearchTerm(item.preferredVendorName ?? "");
      })
      .catch((error: unknown) => {
        const message = error instanceof ApiError ? error.message : "Unable to load inventory item.";
        setStatus(message);
      });
  }, [itemId, mode, token]);

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

    api.getManufacturingStations(token).then(setStations).catch(() => setStations([]));
    api.getPurchaseVendors(token).then(setVendorOptions).catch(() => setVendorOptions([]));
    api.getInventorySkuFamilies(token).then(setSkuFamilies).catch(() => setSkuFamilies([]));
  }, [token]);

  useEffect(() => {
    return () => {
      if (thumbnailPreviewUrl) {
        window.URL.revokeObjectURL(thumbnailPreviewUrl);
      }
    };
  }, [thumbnailPreviewUrl]);

  useEffect(() => {
    if (!token || !itemId || !canReadFiles) {
      setThumbnailAttachment(null);
      replaceThumbnailPreview(null);
      return;
    }

    let cancelled = false;
    const activeToken: string = token;
    const activeItemId: string = itemId;

    async function loadThumbnail() {
      const attachments = await api.getAttachments(activeToken, inventoryThumbnailOwnerType, activeItemId);
      const latestAttachment = attachments[0] ?? null;

      if (!latestAttachment) {
        if (!cancelled) {
          setThumbnailAttachment(null);
          replaceThumbnailPreview(null);
        }
        return;
      }

      const blob = await api.getFileContentBlob(activeToken, latestAttachment.id);
      if (!cancelled) {
        setThumbnailAttachment(latestAttachment);
        replaceThumbnailPreview(window.URL.createObjectURL(blob));
      }
    }

    void loadThumbnail().catch(() => {
      if (!cancelled) {
        setThumbnailAttachment(null);
        replaceThumbnailPreview(null);
      }
    });

    return () => {
      cancelled = true;
    };
  }, [canReadFiles, itemId, token]);

  useEffect(() => {
    const familyId = form.skuBuilder?.familyId ?? null;
    if (!token || !familyId) {
      setSkuLevelOptions([]);
      setSelectedSkuNodeIds([]);
      setSkuPreview(null);
      return;
    }

    let cancelled = false;
    const activeFamilyId: string = familyId;
    const activeToken: string = token;

    async function loadSkuBuilderState() {
      const nextOptions: InventorySkuNodeDto[][] = [];
      let parentNodeId: string | null = null;
      const lineage = selectedSkuNodeIds.filter((value): value is string => Boolean(value));

      for (let levelIndex = 0; levelIndex <= lineage.length; levelIndex += 1) {
        const options = await api.getInventorySkuNodes(activeToken, activeFamilyId, parentNodeId ?? undefined);
        if (!options.length) {
          break;
        }

        nextOptions.push(options);
        const nextSelectedNodeId = lineage[levelIndex];
        if (!nextSelectedNodeId || !options.some((option) => option.id === nextSelectedNodeId)) {
          break;
        }

        parentNodeId = nextSelectedNodeId;
      }

      const leafNodeId = lineage.length > 0 ? lineage[lineage.length - 1] : null;
      const preview = await api.getInventorySkuPreview(activeToken, activeFamilyId, leafNodeId ?? undefined);
      if (!cancelled) {
        setSkuLevelOptions(nextOptions);
        setSkuPreview(preview);
        setForm((current) => ({
          ...current,
          sku: preview.generatedSku,
          skuBuilder: current.skuBuilder ? { familyId: current.skuBuilder.familyId, nodeId: leafNodeId ?? null } : current.skuBuilder,
        }));
      }
    }

    void loadSkuBuilderState().catch(() => {
      if (!cancelled) {
        setSkuLevelOptions([]);
        setSkuPreview(null);
      }
    });

    return () => {
      cancelled = true;
    };
  }, [form.skuBuilder?.familyId, selectedSkuNodeIds, token]);

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

  function updateSkuFamily(familyId: string) {
    if (!familyId) {
      setSelectedSkuNodeIds([]);
      setSkuLevelOptions([]);
      setSkuPreview(null);
      setForm((current) => ({
        ...current,
        skuBuilder: null,
        sku: mode === "edit" && !current.skuBuilder ? current.sku : "",
      }));
      return;
    }

    setSelectedSkuNodeIds([]);
    setForm((current) => ({
      ...current,
      skuBuilder: {
        familyId,
        nodeId: null,
      },
    }));
  }

  function updateSkuNode(levelIndex: number, nodeId: string) {
    setSelectedSkuNodeIds((current) => {
      const next = current.slice(0, levelIndex);
      if (nodeId) {
        next[levelIndex] = nodeId;
      }
      return next;
    });
  }

  function getSelectedVendorName(vendorId: string | null) {
    if (!vendorId) {
      return "";
    }

    return vendorOptions.find((vendor) => vendor.id === vendorId)?.name ?? "";
  }

  function updateBomLine(index: number, nextLine: InventoryBomLineInput) {
    setForm((current) => ({
      ...current,
      bomLines: current.bomLines.map((line, lineIndex) => (lineIndex === index ? nextLine : line)),
    }));
  }

  function updateComponentSearchTerm(index: number, value: string) {
    setComponentSearchTerms((current) => {
      const nextTerms = [...current];
      nextTerms[index] = value;
      return nextTerms;
    });
  }

  function addBomLine() {
    setForm((current) => ({
      ...current,
      bomLines: [
        ...current.bomLines,
        {
          ...emptyInventoryBomLineInput,
          position: current.bomLines.length === 0 ? 10 : Math.max(...current.bomLines.map((line) => line.position)) + 10,
        },
      ],
    }));
    setComponentSearchTerms((current) => [...current, ""]);
  }

  function updateOperation(index: number, nextOperation: InventoryItemOperationInput) {
    setForm((current) => ({
      ...current,
      operations: current.operations.map((operation, operationIndex) => (operationIndex === index ? nextOperation : operation)),
    }));
  }

  function addOperation() {
    setForm((current) => ({
      ...current,
      operations: [
        ...current.operations,
        {
          ...emptyInventoryOperationInput,
          position: current.operations.length === 0 ? 10 : Math.max(...current.operations.map((operation) => operation.position)) + 10,
        },
      ],
    }));
  }

  function removeOperation(index: number) {
    setForm((current) => ({
      ...current,
      operations: current.operations.filter((_operation, operationIndex) => operationIndex !== index),
    }));
  }

  function removeBomLine(index: number) {
    setForm((current) => ({
      ...current,
      bomLines: current.bomLines.filter((_line, lineIndex) => lineIndex !== index),
    }));
    setComponentSearchTerms((current) => current.filter((_term, termIndex) => termIndex !== index));
    setActiveComponentPicker((current) => (current === index ? null : current != null && current > index ? current - 1 : current));
  }

  function handleThumbnailSelect(event: React.ChangeEvent<HTMLInputElement>) {
    const file = event.target.files?.[0];
    if (!file) {
      return;
    }

    setPendingThumbnailFile(file);
    setRemoveThumbnailOnSave(false);
    replaceThumbnailPreview(window.URL.createObjectURL(file));
    event.target.value = "";
  }

  function clearThumbnailSelection() {
    setPendingThumbnailFile(null);
    setRemoveThumbnailOnSave(true);
    replaceThumbnailPreview(null);
  }

  async function syncThumbnail(savedItemId: string) {
    if (!token || !canWriteFiles) {
      return;
    }

    if (thumbnailAttachment && (removeThumbnailOnSave || pendingThumbnailFile)) {
      await api.deleteAttachment(token, thumbnailAttachment.id);
    }

    if (pendingThumbnailFile) {
      const uploaded = await api.uploadFile(token, pendingThumbnailFile, inventoryThumbnailOwnerType, savedItemId);
      setThumbnailAttachment(uploaded);
      const blob = await api.getFileContentBlob(token, uploaded.id);
      replaceThumbnailPreview(window.URL.createObjectURL(blob));
    } else if (removeThumbnailOnSave) {
      setThumbnailAttachment(null);
    }

    setPendingThumbnailFile(null);
    setRemoveThumbnailOnSave(false);
  }

  const pendingRemovalDetail = pendingRemoval
    ? pendingRemoval.kind === "operation"
      ? { label: form.operations[pendingRemoval.index]?.stationId || "this routing operation", typeLabel: "routing operation" }
      : { label: getComponentSku(form.bomLines[pendingRemoval.index]?.componentItemId ?? "") || "this BOM line", typeLabel: "BOM line" }
    : null;

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

    setIsSaving(true);
    setStatus("Saving inventory item...");

    try {
      const saved =
        mode === "create" ? await api.createInventoryItem(token, form) : await api.updateInventoryItem(token, itemId ?? "", form);
      await syncThumbnail(saved.id);
      navigate(`/inventory/items/${saved.id}`);
    } catch (error: unknown) {
      const message = error instanceof ApiError ? error.message : "Unable to save inventory item.";
      setStatus(message);
      setIsSaving(false);
    }
  }

  function forceNavigate(path: string) {
    window.location.assign(path);
  }

  function openSkuMaster() {
    forceNavigate("/inventory/sku-master");
  }

  function closeEditor() {
    forceNavigate(mode === "create" ? "/inventory/items" : `/inventory/items/${itemId}`);
  }

  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">INVENTORY EDITOR</p>
            <h3 className="module-title">{mode === "create" ? "NEW ITEM" : "EDIT ITEM"}</h3>
          </div>
          <div className="flex flex-wrap gap-2">
            <button
              type="button"
              onClick={openSkuMaster}
              className="inline-flex items-center justify-center rounded-2xl border border-line/70 px-2 py-2 text-sm font-semibold text-text"
            >
              SKU master
            </button>
            <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>
        </div>
      </section>
      <section className="surface-panel space-y-3">
        <div className="grid gap-3 xl:grid-cols-2 2xl:grid-cols-4">
          <div className="block 2xl:col-span-2">
            <div className="mb-2 flex items-center justify-between gap-2">
              <span className="text-xs font-semibold uppercase tracking-[0.18em] text-muted">SKU BUILDER</span>
              <button type="button" onClick={openSkuMaster} className="text-xs font-semibold text-brand">
                Manage SKU tree
              </button>
            </div>
            <div className="space-y-3 rounded-[18px] border border-line/70 bg-page/70 p-3">
              <label className="block">
                <span className="mb-2 block text-xs font-semibold uppercase tracking-[0.16em] text-muted">Family</span>
                <select
                  value={form.skuBuilder?.familyId ?? ""}
                  onChange={(event) => updateSkuFamily(event.target.value)}
                  className="w-full rounded-2xl border border-line/70 bg-surface px-2 py-2 text-text outline-none transition focus:border-brand"
                >
                  <option value="">Select family</option>
                  {skuFamilies.filter((family) => family.isActive).map((family) => (
                    <option key={family.id} value={family.id}>
                      {family.code} - {family.name}
                    </option>
                  ))}
                </select>
              </label>
              {skuLevelOptions.length > 0 ? (
                <div className="grid gap-3 xl:grid-cols-2">
                  {skuLevelOptions.map((options, levelIndex) => (
                    <label key={`sku-level-${levelIndex}`} className="block">
                      <span className="mb-2 block text-xs font-semibold uppercase tracking-[0.16em] text-muted">Level {levelIndex + 2}</span>
                      <select
                        value={selectedSkuNodeIds[levelIndex] ?? ""}
                        onChange={(event) => updateSkuNode(levelIndex, event.target.value)}
                        className="w-full rounded-2xl border border-line/70 bg-surface px-2 py-2 text-text outline-none transition focus:border-brand"
                      >
                        <option value="">Stop at this level</option>
                        {options.map((option) => (
                          <option key={option.id} value={option.id}>
                            {option.code} - {option.label}
                          </option>
                        ))}
                      </select>
                    </label>
                  ))}
                </div>
              ) : null}
              <div className="rounded-2xl border border-line/70 bg-surface px-2 py-2">
                <div className="text-xs font-semibold uppercase tracking-[0.16em] text-muted">Generated SKU</div>
                <div className="mt-2 text-lg font-bold text-text">{skuPreview?.generatedSku || form.sku || "Select a family to generate SKU"}</div>
                <div className="mt-2 text-xs text-muted">
                  {skuPreview
                    ? `${skuPreview.familyCode} branch with ${skuPreview.sequenceCode}${String(skuPreview.nextSequenceNumber).padStart(4, "0")} next in sequence.`
                    : form.skuBuilder?.familyId
                      ? `Building from ${getSkuFamilyName(form.skuBuilder.familyId)}.`
                      : "SKU suffix is family-scoped and assigned by the server when the item is saved."}
                </div>
              </div>
              <input
                value={form.sku}
                readOnly
                className="w-full rounded-2xl border border-line/70 bg-page px-2 py-2 text-text outline-none opacity-80"
              />
            </div>
          </div>
          <label className="block 2xl:col-span-2">
            <span className="mb-2 block text-sm font-semibold text-text">Item name</span>
            <input
              value={form.name}
              onChange={(event) => updateField("name", 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">Default cost</span>
            <input
              type="number"
              min={0}
              step={0.01}
              value={form.defaultCost ?? ""}
              onChange={(event) => updateField("defaultCost", event.target.value === "" ? null : Number(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">Default price</span>
            <input
              type="number"
              min={0}
              step={0.01}
              value={form.defaultPrice ?? ""}
              onChange={(event) => updateField("defaultPrice", event.target.value === "" ? null : Number(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>
        <div className="grid gap-4 xl:grid-cols-[220px_1fr]">
          <div className="space-y-3">
            <div>
              <span className="mb-2 block text-sm font-semibold text-text">Thumbnail</span>
              <div className="flex aspect-square items-center justify-center overflow-hidden rounded-[18px] border border-line/70 bg-page/70">
                {thumbnailPreviewUrl ? (
                  <img src={thumbnailPreviewUrl} alt="Inventory thumbnail preview" className="h-full w-full object-cover" />
                ) : (
                  <div className="px-4 text-center text-xs text-muted">No thumbnail selected</div>
                )}
              </div>
            </div>
            <div className="flex flex-wrap gap-2">
              {canWriteFiles ? (
                <label className="inline-flex cursor-pointer items-center justify-center rounded-2xl bg-brand px-3 py-2 text-sm font-semibold text-white">
                  Choose image
                  <input className="hidden" type="file" accept="image/*" onChange={handleThumbnailSelect} />
                </label>
              ) : null}
              {(thumbnailPreviewUrl || thumbnailAttachment) && canWriteFiles ? (
                <button type="button" onClick={clearThumbnailSelection} className="rounded-2xl border border-line/70 px-3 py-2 text-sm font-semibold text-text">
                  Remove
                </button>
              ) : null}
            </div>
          </div>
          <div className="rounded-[18px] border border-line/70 bg-page/60 p-3">
            <div className="text-xs font-semibold uppercase tracking-[0.18em] text-muted">Thumbnail attachment</div>
            <div className="mt-2 text-sm text-muted">
              {pendingThumbnailFile
                ? `${pendingThumbnailFile.name} will upload when you save this item.`
                : removeThumbnailOnSave
                  ? "Thumbnail removal is staged and will apply when you save."
                  : thumbnailAttachment
                    ? `${thumbnailAttachment.originalName} is attached as the current item thumbnail.`
                    : "Attach a product image, render, or reference photo for this item."}
            </div>
          </div>
        </div>
        <div className="grid gap-3 xl:grid-cols-4">
          <label className="block">
            <span className="mb-2 block text-sm font-semibold text-text">Type</span>
            <select
              value={form.type}
              onChange={(event) => updateField("type", event.target.value as InventoryItemInput["type"])}
              className="w-full rounded-2xl border border-line/70 bg-page px-2 py-2 text-text outline-none transition focus:border-brand"
            >
              {inventoryTypeOptions.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">Status</span>
            <select
              value={form.status}
              onChange={(event) => updateField("status", event.target.value as InventoryItemInput["status"])}
              className="w-full rounded-2xl border border-line/70 bg-page px-2 py-2 text-text outline-none transition focus:border-brand"
            >
              {inventoryStatusOptions.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">Unit of measure</span>
            <select
              value={form.unitOfMeasure}
              onChange={(event) => updateField("unitOfMeasure", event.target.value as InventoryItemInput["unitOfMeasure"])}
              className="w-full rounded-2xl border border-line/70 bg-page px-2 py-2 text-text outline-none transition focus:border-brand"
            >
              {inventoryUnitOptions.map((option) => (
                <option key={option.value} value={option.value}>
                  {option.label}
                </option>
              ))}
            </select>
          </label>
          <div className="grid gap-3 sm:grid-cols-2">
            <label className="flex items-center gap-3 rounded-2xl border border-line/70 bg-page px-2 py-2">
              <input type="checkbox" checked={form.isSellable} onChange={(event) => updateField("isSellable", event.target.checked)} />
              <span className="text-sm font-semibold uppercase tracking-[0.08em] text-text">Sellable</span>
            </label>
            <label className="flex items-center gap-3 rounded-2xl border border-line/70 bg-page px-2 py-2">
              <input
                type="checkbox"
                checked={form.isPurchasable}
                onChange={(event) => updateField("isPurchasable", event.target.checked)}
              />
              <span className="text-sm font-semibold uppercase tracking-[0.08em] text-text">Purchasable</span>
            </label>
          </div>
        </div>
        <label className="block xl:max-w-xl">
          <span className="mb-2 block text-sm font-semibold text-text">Preferred vendor</span>
          <div className="relative">
            <input
              value={vendorSearchTerm}
              onChange={(event) => {
                setVendorSearchTerm(event.target.value);
                updateField("preferredVendorId", null);
                setVendorPickerOpen(true);
              }}
              onFocus={() => setVendorPickerOpen(true)}
              onBlur={() => {
                window.setTimeout(() => {
                  setVendorPickerOpen(false);
                  if (form.preferredVendorId) {
                    setVendorSearchTerm(getSelectedVendorName(form.preferredVendorId));
                  }
                }, 120);
              }}
              disabled={!form.isPurchasable}
              placeholder={form.isPurchasable ? "Search vendor" : "Enable purchasable to assign sourcing"}
              className="w-full rounded-2xl border border-line/70 bg-page px-2 py-2 text-text outline-none transition focus:border-brand disabled:cursor-not-allowed disabled:opacity-60"
            />
            {vendorPickerOpen && form.isPurchasable ? (
              <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">
                <button
                  type="button"
                  onMouseDown={(event) => {
                    event.preventDefault();
                    updateField("preferredVendorId", null);
                    setVendorSearchTerm("");
                    setVendorPickerOpen(false);
                  }}
                  className="block w-full border-b border-line/50 px-2 py-2 text-left text-sm transition hover:bg-page/70"
                >
                  <div className="font-semibold text-text">No preferred vendor</div>
                </button>
                {vendorOptions
                  .filter((vendor) => {
                    const query = vendorSearchTerm.trim().toLowerCase();
                    if (!query) {
                      return true;
                    }

                    return vendor.name.toLowerCase().includes(query) || vendor.email.toLowerCase().includes(query);
                  })
                  .slice(0, 12)
                  .map((vendor) => (
                    <button
                      key={vendor.id}
                      type="button"
                      onMouseDown={(event) => {
                        event.preventDefault();
                        updateField("preferredVendorId", vendor.id);
                        setVendorSearchTerm(vendor.name);
                        setVendorPickerOpen(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">{vendor.name}</div>
                      <div className="mt-1 text-xs text-muted">{vendor.email}</div>
                    </button>
                  ))}
              </div>
            ) : null}
          </div>
          <div className="mt-2 text-xs text-muted">
            {form.preferredVendorId ? getSelectedVendorName(form.preferredVendorId) : "Used as the default buy source."}
          </div>
        </label>
        <label className="block">
          <span className="mb-2 block text-sm font-semibold text-text">Description</span>
          <textarea
            value={form.description}
            onChange={(event) => updateField("description", 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>
        <label className="block">
          <span className="mb-2 block text-sm font-semibold text-text">Internal 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>
      </section>
      {form.type === "ASSEMBLY" || form.type === "MANUFACTURED" ? (
        <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">MANUFACTURING ROUTING</p>
              <h4 className="text-lg font-bold text-text">STATION AND TIME TEMPLATE</h4>
            </div>
            <button type="button" onClick={addOperation} className="inline-flex items-center justify-center rounded-2xl border border-line/70 px-2 py-2 text-sm font-semibold text-text">
              Add operation
            </button>
          </div>
          {form.operations.length === 0 ? (
            <div className="mt-3 rounded-[18px] border border-dashed border-line/70 bg-page/60 px-3 py-5 text-center text-sm text-muted">
              Add at least one station operation for this buildable item.
            </div>
          ) : (
            <div className="mt-3 space-y-3">
              {form.operations.map((operation, index) => (
                <div key={`${operation.stationId}-${operation.position}-${index}`} className="rounded-[18px] border border-line/70 bg-page/60 p-3">
                  <div className="grid gap-3 xl:grid-cols-[1.2fr_0.55fr_0.7fr_0.55fr_0.55fr_auto]">
                    <label className="block">
                      <span className="mb-2 block text-xs font-semibold uppercase tracking-[0.16em] text-muted">Station</span>
                      <select
                        value={operation.stationId}
                        onChange={(event) => updateOperation(index, { ...operation, stationId: event.target.value })}
                        className="w-full rounded-2xl border border-line/70 bg-surface px-2 py-2 text-text outline-none transition focus:border-brand"
                      >
                        <option value="">Select station</option>
                        {stations.filter((station) => station.isActive).map((station) => (
                          <option key={station.id} value={station.id}>
                            {station.code} - {station.name}
                          </option>
                        ))}
                      </select>
                    </label>
                    <label className="block">
                      <span className="mb-2 block text-xs font-semibold uppercase tracking-[0.16em] text-muted">Setup</span>
                      <input type="number" min={0} step={1} value={operation.setupMinutes} onChange={(event) => updateOperation(index, { ...operation, setupMinutes: Number.parseInt(event.target.value, 10) || 0 })} className="w-full rounded-2xl border border-line/70 bg-surface px-2 py-2 text-text outline-none transition focus:border-brand" />
                    </label>
                    <label className="block">
                      <span className="mb-2 block text-xs font-semibold uppercase tracking-[0.16em] text-muted">Run / Unit</span>
                      <input type="number" min={0} step={1} value={operation.runMinutesPerUnit} onChange={(event) => updateOperation(index, { ...operation, runMinutesPerUnit: Number.parseInt(event.target.value, 10) || 0 })} className="w-full rounded-2xl border border-line/70 bg-surface px-2 py-2 text-text outline-none transition focus:border-brand" />
                    </label>
                    <label className="block">
                      <span className="mb-2 block text-xs font-semibold uppercase tracking-[0.16em] text-muted">Move</span>
                      <input type="number" min={0} step={1} value={operation.moveMinutes} onChange={(event) => updateOperation(index, { ...operation, moveMinutes: Number.parseInt(event.target.value, 10) || 0 })} className="w-full rounded-2xl border border-line/70 bg-surface px-2 py-2 text-text outline-none transition focus:border-brand" />
                    </label>
                    <label className="block">
                      <span className="mb-2 block text-xs font-semibold uppercase tracking-[0.16em] text-muted">Position</span>
                      <input type="number" min={0} step={10} value={operation.position} onChange={(event) => updateOperation(index, { ...operation, position: Number(event.target.value) || 0 })} className="w-full rounded-2xl border border-line/70 bg-surface px-2 py-2 text-text outline-none transition focus:border-brand" />
                    </label>
                    <div className="flex items-end">
                      <button type="button" onClick={() => setPendingRemoval({ kind: "operation", index })} className="rounded-2xl border border-rose-400/40 px-2 py-2 text-sm font-semibold text-rose-700 dark:text-rose-300">
                        Remove
                      </button>
                    </div>
                  </div>
                  <label className="mt-4 block">
                    <span className="mb-2 block text-xs font-semibold uppercase tracking-[0.16em] text-muted">Notes</span>
                    <input value={operation.notes} onChange={(event) => updateOperation(index, { ...operation, notes: event.target.value })} className="w-full rounded-2xl border border-line/70 bg-surface px-2 py-2 text-text outline-none transition focus:border-brand" />
                  </label>
                </div>
              ))}
            </div>
          )}
        </section>
      ) : null}
      <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">BILL OF MATERIALS</p>
            <h4 className="text-lg font-bold text-text">COMPONENT LINES</h4>
          </div>
          <button
            type="button"
            onClick={addBomLine}
            className="inline-flex items-center justify-center rounded-2xl border border-line/70 px-2 py-2 text-sm font-semibold text-text"
          >
            Add BOM line
          </button>
        </div>
        {form.bomLines.length === 0 ? (
          <div className="mt-3 rounded-[18px] border border-dashed border-line/70 bg-page/60 px-3 py-5 text-center text-sm text-muted">
            No BOM lines added yet.
          </div>
        ) : (
          <div className="mt-3 space-y-3">
            {form.bomLines.map((line, index) => (
              <div key={`${line.componentItemId}-${line.position}-${index}`} className="rounded-[18px] border border-line/70 bg-page/60 p-3">
                <div className="grid gap-3 xl:grid-cols-[1.4fr_0.7fr_0.7fr_0.7fr_auto]">
                  <label className="block">
                    <span className="mb-2 block text-xs font-semibold uppercase tracking-[0.16em] text-muted">Component</span>
                    <div className="relative">
                      <input
                        value={componentSearchTerms[index] ?? getComponentSku(line.componentItemId)}
                        onChange={(event) => {
                          updateComponentSearchTerm(index, event.target.value);
                          updateBomLine(index, { ...line, componentItemId: "" });
                          setActiveComponentPicker(index);
                        }}
                        onFocus={() => setActiveComponentPicker(index)}
                        onBlur={() => {
                          window.setTimeout(() => {
                            setActiveComponentPicker((current) => (current === index ? null : current));
                            if (!form.bomLines[index]?.componentItemId) {
                              updateComponentSearchTerm(index, "");
                            } else {
                              updateComponentSearchTerm(index, getComponentSku(form.bomLines[index].componentItemId));
                            }
                          }, 120);
                        }}
                        placeholder="Search by SKU"
                        className="w-full rounded-2xl border border-line/70 bg-surface px-2 py-2 text-text outline-none transition focus:border-brand"
                      />
                      <div className="mt-2 min-h-5 text-xs text-muted">
                        {getComponentOption(line.componentItemId)?.name ?? "No component selected"}
                      </div>
                      {activeComponentPicker === index ? (
                        <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">
                          {componentOptions
                            .filter((option) => {
                              const query = (componentSearchTerms[index] ?? "").trim().toLowerCase();
                              if (!query) {
                                return true;
                              }

                              return option.sku.toLowerCase().includes(query);
                            })
                            .slice(0, 12)
                            .map((option) => (
                              <button
                                key={option.id}
                                type="button"
                                onMouseDown={(event) => {
                                  event.preventDefault();
                                  updateBomLine(index, { ...line, componentItemId: option.id });
                                  updateComponentSearchTerm(index, option.sku);
                                  setActiveComponentPicker(null);
                                }}
                                title={option.name}
                                className="block w-full border-b border-line/50 px-4 py-2 text-left text-sm font-semibold text-text transition last:border-b-0 hover:bg-page/70"
                              >
                                {option.sku}
                              </button>
                            ))}
                          {componentOptions.filter((option) => {
                            const query = (componentSearchTerms[index] ?? "").trim().toLowerCase();
                            if (!query) {
                              return true;
                            }

                            return option.sku.toLowerCase().includes(query);
                          }).length === 0 ? (
                            <div className="px-2 py-2 text-sm text-muted">No matching components found.</div>
                          ) : null}
                        </div>
                      ) : null}
                    </div>
                  </label>
                  <label className="block">
                    <span className="mb-2 block text-xs font-semibold uppercase tracking-[0.16em] text-muted">Qty</span>
                    <input
                      type="number"
                      min={1}
                      step={1}
                      value={line.quantity}
                      onChange={(event) => updateBomLine(index, { ...line, quantity: Number.parseInt(event.target.value, 10) || 0 })}
                      className="w-full rounded-2xl border border-line/70 bg-surface px-2 py-2 text-text outline-none transition focus:border-brand"
                    />
                  </label>
                  <label className="block">
                    <span className="mb-2 block text-xs font-semibold uppercase tracking-[0.16em] text-muted">UOM</span>
                    <select
                      value={line.unitOfMeasure}
                      onChange={(event) => updateBomLine(index, { ...line, unitOfMeasure: event.target.value as InventoryBomLineInput["unitOfMeasure"] })}
                      className="w-full rounded-2xl border border-line/70 bg-surface px-2 py-2 text-text outline-none transition focus:border-brand"
                    >
                      {inventoryUnitOptions.map((option) => (
                        <option key={option.value} value={option.value}>
                          {option.label}
                        </option>
                      ))}
                    </select>
                  </label>
                  <label className="block">
                    <span className="mb-2 block text-xs font-semibold uppercase tracking-[0.16em] text-muted">Position</span>
                    <input
                      type="number"
                      min={0}
                      step={10}
                      value={line.position}
                      onChange={(event) => updateBomLine(index, { ...line, position: Number(event.target.value) })}
                      className="w-full rounded-2xl border border-line/70 bg-surface px-2 py-2 text-text outline-none transition focus:border-brand"
                    />
                  </label>
                  <div className="flex items-end">
                    <button
                      type="button"
                      onClick={() => setPendingRemoval({ kind: "bom-line", index })}
                      className="rounded-2xl border border-rose-400/40 px-2 py-2 text-sm font-semibold text-rose-700 dark:text-rose-300"
                    >
                      Remove
                    </button>
                  </div>
                </div>
                <label className="mt-4 block">
                  <span className="mb-2 block text-xs font-semibold uppercase tracking-[0.16em] text-muted">Notes</span>
                  <input
                    value={line.notes}
                    onChange={(event) => updateBomLine(index, { ...line, notes: event.target.value })}
                    className="w-full rounded-2xl border border-line/70 bg-surface px-2 py-2 text-text outline-none transition focus:border-brand"
                  />
                </label>
              </div>
            ))}
          </div>
        )}
        <div className="mt-4 flex flex-col gap-2 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 item" : "Save changes"}
          </button>
        </div>
      </section>
      <ConfirmActionDialog
        open={pendingRemoval != null}
        title={pendingRemoval?.kind === "operation" ? "Remove routing operation" : "Remove BOM line"}
        description={
          pendingRemoval && pendingRemovalDetail
            ? `Remove ${pendingRemovalDetail.label} from the item ${pendingRemovalDetail.typeLabel} draft.`
            : "Remove this draft row."
        }
        impact={
          pendingRemoval?.kind === "operation"
            ? "The operation will no longer be copied into new work orders from this item."
            : "The component requirement will be removed from the BOM draft immediately."
        }
        recovery="Add the row back before saving if this change was accidental."
        confirmLabel={pendingRemoval?.kind === "operation" ? "Remove operation" : "Remove BOM line"}
        onClose={() => setPendingRemoval(null)}
        onConfirm={() => {
          if (pendingRemoval?.kind === "operation") {
            removeOperation(pendingRemoval.index);
          } else if (pendingRemoval?.kind === "bom-line") {
            removeBomLine(pendingRemoval.index);
          }
          setPendingRemoval(null);
        }}
      />
    </form>
  );
}

