"use client";

import { useState, useRef } from "react";
import { useRouter } from "next/navigation";
import type { Vendor } from "@prisma/client";
import type { VesselOption, AccountGroup, CompanyOption } from "@/app/(portal)/po/new/new-po-form";
import { SearchableSelect } from "@/components/ui/searchable-select";
import { importPo } from "./actions";
import type { ParsedImport } from "@/app/api/po/import/route";
import { formatCurrency } from "@/lib/utils";

const INPUT_CLS =
  "w-full rounded-lg border border-neutral-300 px-3 py-2.5 text-sm focus:border-primary-500 focus:outline-none focus:ring-2 focus:ring-primary-500/20";

interface Props {
  vessels: VesselOption[];
  accounts: AccountGroup[];
  vendors: Vendor[];
  companies: CompanyOption[];
}

type PreviewState = {
  parsed: ParsedImport;
  title: string;
  vesselId: string;
  accountId: string;
  vendorId: string;
  companyId: string;
};

export function ImportForm({ vessels, accounts, vendors, companies }: Props) {
  const router = useRouter();
  const fileRef = useRef<HTMLInputElement>(null);
  const [parsing, setParsing] = useState(false);
  const [submitting, setSubmitting] = useState(false);
  const [error, setError] = useState("");
  const [preview, setPreview] = useState<PreviewState | null>(null);

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

    setParsing(true);
    setError("");
    setPreview(null);

    const fd = new FormData();
    fd.append("file", file);

    try {
      const res = await fetch("/api/po/import", { method: "POST", body: fd });
      const data = await res.json();
      if (!res.ok || data.error) {
        setError(data.error ?? "Failed to parse file");
        setParsing(false);
        return;
      }

      const parsed: ParsedImport = data.results[0];

      // Auto-match vendor by name (case-insensitive substring)
      const matchedVendor = vendors.find(
        (v) => v.isActive && parsed.vendorName &&
          v.name.toLowerCase().includes(parsed.vendorName.toLowerCase().slice(0, 10))
      );

      // Auto-match company: prefer exact code match, then name fuzzy match
      const matchedCompany = parsed.companyCode
        ? companies.find((c) => c.code?.toUpperCase() === parsed.companyCode?.toUpperCase())
            ?? companies.find((c) =>
                parsed.companyName && (
                  c.name.toLowerCase().includes(parsed.companyName.toLowerCase().slice(0, 8)) ||
                  parsed.companyName.toLowerCase().includes(c.name.toLowerCase().slice(0, 8))
                )
              )
        : companies.find((c) =>
            parsed.companyName && (
              c.name.toLowerCase().includes(parsed.companyName.toLowerCase().slice(0, 8)) ||
              parsed.companyName.toLowerCase().includes(c.name.toLowerCase().slice(0, 8))
            )
          );

      // Auto-match vessel: prefer exact code match from PO number
      const matchedVessel = parsed.costCentreCode
        ? vessels.find((v) => v.code.toUpperCase() === parsed.costCentreCode!.toUpperCase())
        : null;

      setPreview({
        parsed,
        title: parsed.vendorName
          ? `${parsed.vendorName} — Import`
          : "Imported Purchase Order",
        vesselId: matchedVessel?.id ?? vessels[0]?.id ?? "",
        accountId: accounts[0]?.items[0]?.id ?? "",
        vendorId: matchedVendor?.id ?? "",
        companyId: matchedCompany?.id ?? (companies[0]?.id ?? ""),
      });
    } catch {
      setError("Network error while parsing file");
    } finally {
      setParsing(false);
    }
  }

  async function handleSubmit(e: React.FormEvent<HTMLFormElement>) {
    e.preventDefault();
    if (!preview) return;
    setSubmitting(true);
    setError("");

    const result = await importPo({
      title: preview.title,
      vesselId: preview.vesselId,
      companyId: preview.companyId || undefined,
      accountId: preview.accountId,
      originalPoNumber: preview.parsed.poNumber || undefined,
      vendorId: preview.vendorId || undefined,
      parsedVendorName: preview.parsed.vendorName || undefined,
      parsedVendorAddress: preview.parsed.vendorAddress || undefined,
      parsedVendorContact: preview.parsed.vendorContact || undefined,
      piQuotationNo: preview.parsed.piQuotationNo || undefined,
      placeOfDelivery: preview.parsed.placeOfDelivery || undefined,
      tcDelivery: preview.parsed.tcDelivery || undefined,
      tcDispatch: preview.parsed.tcDispatch || undefined,
      tcInspection: preview.parsed.tcInspection || undefined,
      tcTransitInsurance: preview.parsed.tcTransitInsurance || undefined,
      tcPaymentTerms: preview.parsed.tcPaymentTerms || undefined,
      tcOthers: preview.parsed.tcOthers || undefined,
      lineItems: preview.parsed.lineItems,
    });

    if ("error" in result) {
      setError(result.error);
      setSubmitting(false);
    } else {
      router.push(`/po/${result.id}`);
    }
  }

  function reset() {
    setPreview(null);
    setError("");
    if (fileRef.current) fileRef.current.value = "";
  }

  if (!preview) {
    return (
      <div className="rounded-lg border border-neutral-200 bg-white p-8 text-center">
        <div className="mb-4">
          <div className="mx-auto mb-3 flex h-14 w-14 items-center justify-center rounded-full bg-primary-50">
            <svg className="h-7 w-7 text-primary-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.5} d="M9 13h6m-3-3v6m5 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" />
            </svg>
          </div>
          <p className="text-sm font-medium text-neutral-900 mb-1">Upload Excel PO file</p>
          <p className="text-xs text-neutral-500">
            Supports the Pelagia PO Excel format (.xlsx). Each sheet is treated as one PO.
          </p>
        </div>

        <label className="cursor-pointer">
          <input
            ref={fileRef}
            type="file"
            accept=".xlsx,.xls"
            onChange={handleFile}
            className="sr-only"
            disabled={parsing}
          />
          <span className={`inline-flex items-center gap-2 rounded-lg bg-primary-600 px-5 py-2.5 text-sm font-semibold text-white hover:bg-primary-700 transition-colors ${parsing ? "opacity-60 cursor-not-allowed" : ""}`}>
            {parsing ? "Parsing…" : "Choose Excel File"}
          </span>
        </label>

        {error && (
          <p className="mt-4 text-sm text-danger-700 bg-danger-50 rounded-lg px-3 py-2">{error}</p>
        )}
      </div>
    );
  }

  const { parsed } = preview;
  const total = parsed.lineItems.reduce(
    (s, li) => s + li.quantity * li.unitPrice * (1 + (li.gstRate ?? 0.18)), 0
  );

  return (
    <form onSubmit={handleSubmit} className="space-y-6">
      {/* Extracted data banner */}
      <div className="rounded-lg border border-primary-100 bg-primary-50 px-4 py-3 text-sm text-primary-800 space-y-1">
        <div>
          <span className="font-semibold">Parsed from file.</span>{" "}
          {parsed.vendorName && <>Vendor: <strong>{parsed.vendorName}</strong>. </>}
          {parsed.piQuotationNo && <>Quotation: <strong>{parsed.piQuotationNo}</strong>. </>}
          This PO will be saved directly as <strong>Closed</strong> — no approval needed.
        </div>
        {parsed.poNumber && (
          <div className="text-xs text-primary-700">
            PO Number: <span className="font-mono font-semibold">{parsed.poNumber}</span>
            {parsed.companyCode && <> · Company: <strong>{parsed.companyCode}</strong></>}
            {parsed.costCentreCode && <> · Cost Centre: <strong>{parsed.costCentreCode}</strong></>}
            {parsed.poSequenceId !== null && <> · ID: <strong>{parsed.poSequenceId}</strong></>}
          </div>
        )}
      </div>

      {/* User-required fields */}
      <section className="rounded-lg border border-neutral-200 bg-white p-6 space-y-4">
        <h2 className="text-base font-semibold text-neutral-900">Order Information</h2>
        <div>
          <label className="block text-sm font-medium text-neutral-700 mb-1.5">
            Title <span className="text-danger">*</span>
          </label>
          <input
            value={preview.title}
            onChange={(e) => setPreview({ ...preview, title: e.target.value })}
            required
            className={INPUT_CLS}
          />
        </div>
        {companies.length > 0 && (
          <div>
            <label className="block text-sm font-medium text-neutral-700 mb-1.5">
              Company <span className="text-danger">*</span>
              {preview.parsed.companyName && (
                <span className="ml-2 text-xs font-normal text-primary-600">
                  Detected: "{preview.parsed.companyName}"
                </span>
              )}
            </label>
            <select
              value={preview.companyId}
              onChange={(e) => setPreview({ ...preview, companyId: e.target.value })}
              required
              className={INPUT_CLS}
            >
              <option value="">Select company…</option>
              {companies.map((c) => (
                <option key={c.id} value={c.id}>{c.name}</option>
              ))}
            </select>
          </div>
        )}
        <div className="grid grid-cols-2 gap-4">
          <div>
            <label className="block text-sm font-medium text-neutral-700 mb-1.5">
              Cost Centre <span className="text-danger">*</span>
            </label>
            <select
              value={preview.vesselId}
              onChange={(e) => setPreview({ ...preview, vesselId: e.target.value })}
              required
              className={INPUT_CLS}
            >
              <option value="">Select cost centre…</option>
              {vessels.map((v) => (
                <option key={v.id} value={v.id}>{v.code} — {v.name}</option>
              ))}
            </select>
          </div>
          <div>
            <label className="block text-sm font-medium text-neutral-700 mb-1.5">
              Accounting Code <span className="text-danger">*</span>
            </label>
            <SearchableSelect
              name="__import_account"
              value={preview.accountId}
              onChange={(v) => setPreview({ ...preview, accountId: v })}
              groups={accounts}
              placeholder="Search accounting code…"
              required
            />
          </div>
        </div>
        <div>
          <label className="block text-sm font-medium text-neutral-700 mb-1.5">Vendor</label>
          <select
            value={preview.vendorId}
            onChange={(e) => setPreview({ ...preview, vendorId: e.target.value })}
            className={INPUT_CLS}
          >
            <option value="">No vendor / add later</option>
            {vendors.filter((v) => v.isActive).map((v) => (
              <option key={v.id} value={v.id}>
                {v.name}{v.vendorId ? ` (${v.vendorId})` : " (unverified)"}
              </option>
            ))}
          </select>
          {parsed.vendorName && !preview.vendorId && (
            <p className="mt-1 text-xs text-success-700 bg-success-50 rounded px-2 py-1">
              ✓ Vendor &ldquo;{parsed.vendorName}&rdquo; will be auto-created on submit.
            </p>
          )}
        </div>
      </section>

      {/* Line items preview */}
      <section className="rounded-lg border border-neutral-200 bg-white p-6">
        <div className="flex items-center justify-between mb-4">
          <h2 className="text-base font-semibold text-neutral-900">
            Line Items <span className="ml-2 text-sm font-normal text-neutral-500">({parsed.lineItems.length} items)</span>
          </h2>
          <p className="text-xs text-success-700 bg-success-50 rounded px-2 py-1">
            ✓ Products will be auto-created in the catalogue on submit
          </p>
        </div>
        <div className="overflow-x-auto">
          <table className="w-full text-sm">
            <thead>
              <tr className="border-b border-neutral-200">
                <th className="pb-2 text-left font-medium text-neutral-600 w-full">Description</th>
                <th className="pb-2 text-right font-medium text-neutral-600 pl-4">Qty</th>
                <th className="pb-2 text-left font-medium text-neutral-600 pl-3">Unit</th>
                <th className="pb-2 text-right font-medium text-neutral-600 pl-4">Unit Price</th>
                <th className="pb-2 text-right font-medium text-neutral-600 pl-4">GST%</th>
                <th className="pb-2 text-right font-medium text-neutral-600 pl-4">Total</th>
              </tr>
            </thead>
            <tbody className="divide-y divide-neutral-100">
              {parsed.lineItems.map((li, i) => {
                const taxable = li.quantity * li.unitPrice;
                const lineTotal = taxable * (1 + (li.gstRate ?? 0.18));
                return (
                  <tr key={i}>
                    <td className="py-2 pr-4 text-neutral-900">{li.name}</td>
                    <td className="py-2 pl-4 text-right">{li.quantity}</td>
                    <td className="py-2 pl-3 text-neutral-500">{li.unit}</td>
                    <td className="py-2 pl-4 text-right">{formatCurrency(li.unitPrice)}</td>
                    <td className="py-2 pl-4 text-right text-neutral-500">{Math.round((li.gstRate ?? 0.18) * 100)}%</td>
                    <td className="py-2 pl-4 text-right font-medium">{formatCurrency(lineTotal)}</td>
                  </tr>
                );
              })}
            </tbody>
            <tfoot>
              <tr className="border-t border-neutral-200">
                <td colSpan={5} className="pt-3 text-right text-sm font-semibold text-neutral-900">Grand Total</td>
                <td className="pt-3 pl-4 text-right text-sm font-semibold text-neutral-900">{formatCurrency(total)}</td>
              </tr>
            </tfoot>
          </table>
        </div>
      </section>

      {error && (
        <p className="text-sm text-danger-700 bg-danger-50 rounded-lg px-3 py-2">{error}</p>
      )}

      <div className="flex items-center gap-3">
        <button
          type="button"
          onClick={reset}
          className="rounded-lg border border-neutral-300 bg-white px-4 py-2.5 text-sm font-medium text-neutral-700 hover:bg-neutral-50 transition-colors"
        >
          ← Upload Different File
        </button>
        <button
          type="submit"
          disabled={submitting || !preview.vesselId || !preview.accountId || (companies.length > 0 && !preview.companyId)}
          className="rounded-lg bg-primary-600 px-5 py-2.5 text-sm font-semibold text-white hover:bg-primary-700 disabled:opacity-60 transition-colors"
        >
          {submitting ? "Importing…" : "Import & Close PO"}
        </button>
      </div>
    </form>
  );
}
