import { useState } from "react";
import { createFileRoute, Link, notFound, useNavigate } from "@tanstack/react-router";
import {
  AlertTriangle,
  ArrowLeft,
  Check,
  CloudUpload,
  Copy,
  Info,
  MoreHorizontal,
  Send,
  Sparkles,
  X,
  ZoomIn,
  ZoomOut,
} from "lucide-react";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Textarea } from "@/components/ui/textarea";
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import { SectionCard } from "@/components/ledger/Primitives";
import { StatusBadge } from "@/components/ledger/StatusBadge";
import { ConfidenceIndicator } from "@/components/ledger/ConfidenceIndicator";
import { eur, useLedger } from "@/lib/ledger-store";
import type { Invoice } from "@/lib/ledger-types";

export const Route = createFileRoute("/firm/invoices/$id")({
  head: () => ({
    meta: [
      { title: "Invoice review — Abdelouhab" },
      {
        name: "description",
        content: "Verify extracted data, review the AI booking suggestion and sync approved work to SnelStart.",
      },
      { property: "og:title", content: "Invoice review — Abdelouhab" },
      { property: "og:description", content: "The Abdelouhab review workspace for a single invoice." },
    ],
  }),
  component: InvoiceReview,
});

function InvoiceReview() {
  const { id } = Route.useParams();
  const navigate = useNavigate();
  const {
    getInvoice,
    clients,
    clientName,
    updateInvoiceFields,
    updateSuggestion,
    approveInvoice,
    rejectInvoice,
    syncInvoice,
    createQuery,
    settings,
  } = useLedger();

  const invoice = getInvoice(id);
  const [zoom, setZoom] = useState(1);
  const [question, setQuestion] = useState("");

  if (!invoice) {
    throw notFound();
  }

  const client = clients.find((c) => c.id === invoice.clientId);
  const canSync = invoice.status === "Approved" || invoice.status === "Auto-ready";

  return (
    <div className="space-y-5">
      <div className="flex flex-wrap items-start justify-between gap-3">
        <div className="min-w-0">
          <nav aria-label="Breadcrumb" className="text-[12.5px] text-muted-foreground">
            <Link to="/firm/inbox" className="hover:text-foreground">
              Document inbox
            </Link>
            <span aria-hidden="true"> / </span>
            <span className="text-foreground">{invoice.number}</span>
          </nav>
          <h1 className="mt-1.5 font-display text-[28px] leading-tight">{invoice.supplier}</h1>
          <div className="mt-2 flex flex-wrap items-center gap-3">
            <StatusBadge status={invoice.status} />
            <span className="text-[13px] text-muted-foreground">{clientName(invoice.clientId)}</span>
            <div className="w-40">
              <ConfidenceIndicator value={invoice.confidence} compact />
            </div>
          </div>
        </div>
        <div className="flex items-center gap-2">
          <DropdownMenu>
            <DropdownMenuTrigger asChild>
              <Button variant="ghost" size="icon" aria-label="More actions">
                <MoreHorizontal size={18} />
              </Button>
            </DropdownMenuTrigger>
            <DropdownMenuContent align="end">
              <DropdownMenuItem onSelect={() => navigate({ to: "/firm/activity" })}>
                View activity
              </DropdownMenuItem>
              <DropdownMenuItem onSelect={() => navigate({ to: "/firm/queries" })}>
                View client queries
              </DropdownMenuItem>
            </DropdownMenuContent>
          </DropdownMenu>
          <Button variant="outline" asChild>
            <Link to="/firm/inbox">
              <ArrowLeft size={16} /> Back to inbox
            </Link>
          </Button>
        </div>
      </div>

      {invoice.duplicateOf ? (
        <div className="flex flex-wrap items-start gap-3 rounded-xl border border-attention/30 bg-attention-soft px-4 py-3">
          <AlertTriangle size={18} className="mt-0.5 text-attention" aria-hidden="true" />
          <div className="min-w-0 flex-1">
            <p className="text-[13.5px] font-medium text-foreground">Possible duplicate invoice</p>
            <p className="mt-0.5 text-[13px] leading-6 text-muted-foreground">
              Supplier, amount, date and payment reference closely match an existing document.
            </p>
          </div>
          <Button variant="outline" size="sm" asChild>
            <Link to="/firm/invoices/$id" params={{ id: invoice.duplicateOf }}>
              <Copy size={15} /> View matching invoice
            </Link>
          </Button>
        </div>
      ) : null}

      {invoice.status === "Sync failed" && invoice.syncError ? (
        <div className="flex items-start gap-3 rounded-xl border border-destructive/25 bg-destructive-soft px-4 py-3">
          <AlertTriangle size={18} className="mt-0.5 text-destructive" aria-hidden="true" />
          <p className="text-[13.5px] text-foreground">{invoice.syncError}</p>
        </div>
      ) : null}

      <div className="grid gap-4 lg:grid-cols-[1.2fr_1fr]">
        <div className="space-y-4">
          <SectionCard
            title="Document preview"
            description="Scanned source document"
            action={
              <div className="flex items-center gap-1">
                <Button
                  variant="ghost"
                  size="icon"
                  aria-label="Zoom out"
                  onClick={() => setZoom((z) => Math.max(0.7, z - 0.1))}
                >
                  <ZoomOut size={16} />
                </Button>
                <span className="num w-10 text-center text-[12px] text-muted-foreground">
                  {Math.round(zoom * 100)}%
                </span>
                <Button
                  variant="ghost"
                  size="icon"
                  aria-label="Zoom in"
                  onClick={() => setZoom((z) => Math.min(1.4, z + 0.1))}
                >
                  <ZoomIn size={16} />
                </Button>
              </div>
            }
            bodyClassName="overflow-auto bg-muted/50 p-5"
          >
            <InvoicePreview invoice={invoice} zoom={zoom} clientLabel={clientName(invoice.clientId)} />
          </SectionCard>

          <ExtractedFields invoice={invoice} onSave={(patch) => updateInvoiceFields(invoice.id, patch)} />

          <SectionCard title="Line items" description="Editable document lines" bodyClassName="overflow-x-auto">
            <LineItemsTable invoice={invoice} onSave={(lines) => updateInvoiceFields(invoice.id, { lines })} />
          </SectionCard>
        </div>

        <div className="space-y-4 lg:sticky lg:top-20 lg:self-start">
          <SectionCard
            title="AI booking suggestion"
            description="Prepared by Abdelouhab from historical bookings"
            action={<Sparkles size={16} className="text-primary" aria-hidden="true" />}
            bodyClassName="p-5 space-y-4"
          >
            <ConfidenceIndicator value={invoice.confidence} />
            <div className="rounded-lg border border-border bg-muted/50 p-3">
              <p className="text-[12px] font-semibold text-foreground">Why this suggestion?</p>
              <p className="mt-1 text-[13px] leading-6 text-muted-foreground">{invoice.suggestion.reasoning}</p>
            </div>
            {invoice.suggestion.editedBy ? (
              <p className="text-[11.5px] text-muted-foreground">Edited by {invoice.suggestion.editedBy}</p>
            ) : null}
            <div className="grid gap-3 sm:grid-cols-2">
              <FieldInput
                label="Ledger account"
                value={invoice.suggestion.ledger}
                onSave={(v) => updateSuggestion(invoice.id, { ledger: v })}
              />
              <FieldInput
                label="VAT code"
                value={invoice.suggestion.vatCode}
                onSave={(v) => updateSuggestion(invoice.id, { vatCode: v })}
              />
              <FieldInput
                label="Expense category"
                value={invoice.suggestion.category}
                onSave={(v) => updateSuggestion(invoice.id, { category: v })}
              />
              <FieldInput
                label="Relation"
                value={invoice.suggestion.relation}
                onSave={(v) => updateSuggestion(invoice.id, { relation: v })}
              />
            </div>
          </SectionCard>

          <SectionCard title="Workflow" description="Approve, reject and sync" bodyClassName="space-y-3 p-5">
            <div className="flex flex-wrap gap-2">
              <Button onClick={() => approveInvoice(invoice.id)} disabled={invoice.status === "Synced"}>
                <Check size={16} /> Approve
              </Button>
              <Button variant="outline" onClick={() => rejectInvoice(invoice.id)}>
                <X size={16} /> Reject
              </Button>
            </div>
            <div>
              <Button
                variant={canSync ? "default" : "secondary"}
                className="w-full"
                disabled={!canSync}
                title={canSync ? undefined : "Only approved or auto-ready invoices can sync"}
                onClick={() => syncInvoice(invoice.id)}
              >
                <CloudUpload size={16} /> Sync to SnelStart
              </Button>
              {!canSync ? (
                <p className="mt-2 flex items-start gap-1.5 text-[12px] text-muted-foreground">
                  <Info size={14} className="mt-0.5 shrink-0" aria-hidden="true" />
                  Sync is available once the invoice is Approved or Auto-ready (
                  {settings.threshold}% confidence threshold).
                </p>
              ) : null}
              {client && !client.snelstart ? (
                <p className="mt-2 flex items-start gap-1.5 text-[12px] text-attention">
                  <AlertTriangle size={14} className="mt-0.5 shrink-0" aria-hidden="true" />
                  SnelStart is not connected for {client.name}; syncing will fail.
                </p>
              ) : null}
            </div>
          </SectionCard>

          <SectionCard title="Ask the client" description="Create a linked query" bodyClassName="space-y-3 p-5">
            <Label htmlFor="ask-client" className="text-[12px] text-muted-foreground">
              Question
            </Label>
            <Textarea
              id="ask-client"
              value={question}
              onChange={(e) => setQuestion(e.target.value)}
              placeholder="What do you need clarification on?"
              className="min-h-24 bg-surface"
            />
            <Button
              variant="outline"
              disabled={!question.trim()}
              onClick={() => {
                createQuery(invoice.clientId, question.trim(), invoice.id);
                setQuestion("");
              }}
            >
              <Send size={16} /> Send query
            </Button>
          </SectionCard>
        </div>
      </div>
    </div>
  );
}

function FieldInput({
  label,
  value,
  onSave,
  type = "text",
}: {
  label: string;
  value: string;
  onSave: (v: string) => void;
  type?: string;
}) {
  const [draft, setDraft] = useState(value);
  const id = `f-${label.replace(/\s+/g, "-").toLowerCase()}`;
  return (
    <div>
      <Label htmlFor={id} className="text-[12px] text-muted-foreground">
        {label}
      </Label>
      <Input
        id={id}
        type={type}
        value={draft}
        onChange={(e) => setDraft(e.target.value)}
        onBlur={() => draft !== value && onSave(draft)}
        className="mt-1 h-9 bg-surface"
      />
    </div>
  );
}

function ExtractedFields({
  invoice,
  onSave,
}: {
  invoice: Invoice;
  onSave: (patch: Partial<Invoice>) => void;
}) {
  const [draft, setDraft] = useState({
    supplier: invoice.supplier,
    number: invoice.number,
    invoiceDate: invoice.invoiceDate,
    dueDate: invoice.dueDate,
    vatAmount: String(invoice.vatAmount),
    total: String(invoice.total),
    currency: invoice.currency,
    paymentRef: invoice.paymentRef,
  });

  const set = (k: keyof typeof draft) => (e: React.ChangeEvent<HTMLInputElement>) =>
    setDraft((d) => ({ ...d, [k]: e.target.value }));

  const fields: { key: keyof typeof draft; label: string; type?: string }[] = [
    { key: "supplier", label: "Supplier" },
    { key: "number", label: "Invoice number" },
    { key: "invoiceDate", label: "Invoice date", type: "date" },
    { key: "dueDate", label: "Due date", type: "date" },
    { key: "vatAmount", label: "VAT amount", type: "number" },
    { key: "total", label: "Total", type: "number" },
    { key: "currency", label: "Currency" },
    { key: "paymentRef", label: "Payment reference" },
  ];

  return (
    <SectionCard title="Extracted fields" description="Verify what Abdelouhab read from the document" bodyClassName="p-5">
      <div className="grid gap-3 sm:grid-cols-2">
        {fields.map((f) => (
          <div key={f.key}>
            <Label htmlFor={`ex-${f.key}`} className="text-[12px] text-muted-foreground">
              {f.label}
            </Label>
            <Input
              id={`ex-${f.key}`}
              type={f.type ?? "text"}
              value={draft[f.key]}
              onChange={set(f.key)}
              className="mt-1 h-9 bg-surface"
            />
          </div>
        ))}
      </div>
      <div className="mt-4">
        <Button
          onClick={() =>
            onSave({
              supplier: draft.supplier,
              number: draft.number,
              invoiceDate: draft.invoiceDate,
              dueDate: draft.dueDate,
              vatAmount: Number(draft.vatAmount) || 0,
              total: Number(draft.total) || 0,
              currency: draft.currency,
              paymentRef: draft.paymentRef,
            })
          }
        >
          Save changes
        </Button>
      </div>
    </SectionCard>
  );
}

function LineItemsTable({
  invoice,
  onSave,
}: {
  invoice: Invoice;
  onSave: (lines: Invoice["lines"]) => void;
}) {
  const [lines, setLines] = useState(invoice.lines);

  const update = (id: string, patch: Partial<Invoice["lines"][number]>) =>
    setLines((prev) => prev.map((l) => (l.id === id ? { ...l, ...patch } : l)));

  return (
    <div>
      <table className="w-full min-w-[620px] text-[13.5px]">
        <thead className="border-b border-border bg-muted/50 text-[11.5px] tracking-wide text-muted-foreground uppercase">
          <tr>
            <th className="px-5 py-2.5 text-left font-semibold">Description</th>
            <th className="px-3 py-2.5 text-right font-semibold">Qty</th>
            <th className="px-3 py-2.5 text-right font-semibold">Unit price</th>
            <th className="px-3 py-2.5 text-right font-semibold">VAT</th>
            <th className="px-5 py-2.5 text-right font-semibold">Total</th>
          </tr>
        </thead>
        <tbody className="divide-y divide-border">
          {lines.map((l) => (
            <tr key={l.id}>
              <td className="px-5 py-2">
                <Input
                  value={l.description}
                  aria-label="Line description"
                  onChange={(e) => update(l.id, { description: e.target.value })}
                  className="h-8 border-transparent bg-transparent px-1 hover:border-border focus:bg-surface"
                />
              </td>
              <td className="px-3 py-2 text-right">
                <Input
                  type="number"
                  value={l.qty}
                  aria-label="Quantity"
                  onChange={(e) => update(l.id, { qty: Number(e.target.value) })}
                  className="num h-8 w-20 border-transparent bg-transparent px-1 text-right hover:border-border focus:bg-surface"
                />
              </td>
              <td className="px-3 py-2 text-right">
                <Input
                  type="number"
                  value={l.unitPrice}
                  aria-label="Unit price"
                  onChange={(e) => update(l.id, { unitPrice: Number(e.target.value) })}
                  className="num h-8 w-24 border-transparent bg-transparent px-1 text-right hover:border-border focus:bg-surface"
                />
              </td>
              <td className="num px-3 py-2 text-right text-muted-foreground">{l.vatRate}%</td>
              <td className="num px-5 py-2 text-right font-medium">{eur(l.qty * l.unitPrice)}</td>
            </tr>
          ))}
        </tbody>
      </table>
      <div className="flex justify-end px-5 py-3">
        <Button variant="outline" size="sm" onClick={() => onSave(lines)}>
          Save line items
        </Button>
      </div>
    </div>
  );
}

function InvoicePreview({
  invoice,
  zoom,
  clientLabel,
}: {
  invoice: Invoice;
  zoom: number;
  clientLabel: string;
}) {
  const net = invoice.total - invoice.vatAmount;
  return (
    <div
      className="mx-auto w-full max-w-[560px] origin-top rounded-md border border-border bg-surface p-7 shadow-sm"
      style={{ transform: `scale(${zoom})` }}
    >
      <div className="flex items-start justify-between">
        <div>
          <p className="font-display text-[18px]">{invoice.supplier}</p>
          <p className="mt-1 text-[11.5px] leading-5 text-muted-foreground">
            Industrieweg 14
            <br />
            3542 AD Utrecht
            <br />
            BTW NL8123.45.678.B01
          </p>
        </div>
        <div className="text-right text-[11.5px] text-muted-foreground">
          <p className="text-[13px] font-semibold tracking-wide text-foreground uppercase">Factuur</p>
          <p className="mt-1">Nr. {invoice.number}</p>
          <p>Datum {invoice.invoiceDate}</p>
          <p>Vervaldatum {invoice.dueDate}</p>
        </div>
      </div>

      <div className="mt-6 border-t border-border pt-3 text-[11.5px] text-muted-foreground">
        <p className="font-medium text-foreground">Aan</p>
        <p>{clientLabel}</p>
      </div>

      <table className="mt-5 w-full text-[11.5px]">
        <thead className="border-b border-border text-left text-muted-foreground">
          <tr>
            <th className="py-1.5 font-medium">Omschrijving</th>
            <th className="py-1.5 text-right font-medium">Aantal</th>
            <th className="py-1.5 text-right font-medium">Prijs</th>
            <th className="py-1.5 text-right font-medium">Bedrag</th>
          </tr>
        </thead>
        <tbody>
          {invoice.lines.map((l) => (
            <tr key={l.id} className="border-b border-border/60">
              <td className="py-1.5">{l.description}</td>
              <td className="num py-1.5 text-right">{l.qty}</td>
              <td className="num py-1.5 text-right">{eur(l.unitPrice)}</td>
              <td className="num py-1.5 text-right">{eur(l.qty * l.unitPrice)}</td>
            </tr>
          ))}
        </tbody>
      </table>

      <div className="mt-4 ml-auto w-52 space-y-1 text-[11.5px]">
        <div className="flex justify-between text-muted-foreground">
          <span>Subtotaal</span>
          <span className="num">{eur(net)}</span>
        </div>
        <div className="flex justify-between text-muted-foreground">
          <span>BTW</span>
          <span className="num">{eur(invoice.vatAmount)}</span>
        </div>
        <div className="flex justify-between border-t border-border pt-1 text-[13px] font-semibold">
          <span>Totaal</span>
          <span className="num">{eur(invoice.total)}</span>
        </div>
      </div>

      <p className="mt-6 text-[10.5px] text-muted-foreground">
        Betaling binnen 30 dagen o.v.v. {invoice.paymentRef}
      </p>
    </div>
  );
}
