"use client"

import { use, useEffect, useMemo, useState } from "react"
import Link from "next/link"
import { useRouter } from "next/navigation"
import { ArrowLeft, ExternalLink, Minus, Plus, Printer, Save, Send, Undo2, X } from "lucide-react"

import { salesApi } from "@/lib/api/sales"
import { customersApi } from "@/lib/api/customers"
import { itemsApi } from "@/lib/api/items"
import { uomsApi } from "@/lib/api/uoms"
import { baseUomLabel } from "@/lib/uom-label"
import { warehousesApi } from "@/lib/api/warehouses"
import { errorMessage } from "@/lib/error-map"
import { cn } from "@/lib/utils"
import { getSuggestedUnitPrice } from "@/lib/sales-line-utils"
import { Customer } from "@/types/customers"
import { ItemListItem, Uom, Warehouse } from "@/types/master-data"
import { CreateSalesInvoiceLineRequest, SalesInvoice, SalesInvoicePayment, SalesInvoicePostingCheck, SalesInvoiceStatus, SalesInvoiceType } from "@/types/sales"
import { toast } from "@/components/ui/toast"
import { Label } from "@/components/ui/label"
import { Button } from "@/components/ui/button"
import { SalesInvoicePaymentDialog } from "@/components/sales/SalesInvoicePaymentDialog"

type Line = CreateSalesInvoiceLineRequest & { key: string }

const money = new Intl.NumberFormat("en-LK", {
  style: "currency",
  currency: "LKR",
  minimumFractionDigits: 2,
})

const blankLine = (key: string): Line => ({
  key,
  itemId: 0,
  warehouseId: 0,
  qty: 1,
  freeQty: 0,
  unitPrice: null,
  allowManualPriceOverride: true,
  discountMode: "Percentage",
  discountPct: 0,
  discountAmount: 0,
  discountValue: 0,
  taxPct: 0,
  isFreeIssue: false,
  parentLineId: null,
})

function statusClass(status: SalesInvoiceStatus) {
  switch (status) {
    case "Draft":
      return "border-amber-200 bg-amber-50 text-amber-800"
    case "Posted":
      return "border-emerald-200 bg-emerald-50 text-emerald-800"
    case "Cancelled":
      return "border-rose-200 bg-rose-50 text-rose-800"
  }
}

export default function SalesInvoiceDetailPage({ params }: { params: Promise<{ id: string }> }) {
  const router = useRouter()
  const resolvedParams = use(params)
  const invoiceId = Number(resolvedParams.id)

  const [invoice, setInvoice] = useState<SalesInvoice | null>(null)
  const [customers, setCustomers] = useState<Customer[]>([])
  const [items, setItems] = useState<ItemListItem[]>([])
  const [uoms, setUoms] = useState<Uom[]>([])
  const [warehouses, setWarehouses] = useState<Warehouse[]>([])
  const [lines, setLines] = useState<Line[]>([blankLine("line-1")])
  const [customerId, setCustomerId] = useState<number | null>(null)
  const [warehouseId, setWarehouseId] = useState<number | null>(null)
  const [invoiceType, setInvoiceType] = useState<SalesInvoiceType>("B2C")
  const [etag, setEtag] = useState<string | null>(null)
  const [postingCheck, setPostingCheck] = useState<SalesInvoicePostingCheck | null>(null)
  const [error, setError] = useState<string | null>(null)
  const [saving, setSaving] = useState(false)
  const [busy, setBusy] = useState<"post" | "cancel" | null>(null)
  const [payments, setPayments] = useState<SalesInvoicePayment[]>([])
  const [payDialogOpen, setPayDialogOpen] = useState(false)

  useEffect(() => {
    if (!Number.isFinite(invoiceId)) {
      setError(`Invalid invoice id '${resolvedParams.id}'.`)
      return
    }

    Promise.all([
      customersApi.list({ pageSize: 200 }),
      itemsApi.list({ pageSize: 200 }),
      uomsApi.list({ pageSize: 200 }),
      warehousesApi.list({ pageSize: 200 }),
      salesApi.getInvoice(invoiceId),
    ])
      .then(([customerRes, itemRes, uomRes, warehouseRes, doc]) => {
        setCustomers(customerRes.items)
        setItems(itemRes.items)
        setUoms(uomRes.items)
        setWarehouses(warehouseRes.items)
        setInvoice(doc.data)
        setEtag(doc.etag)
        setCustomerId(doc.data.customerId)
        setWarehouseId(doc.data.warehouseId)
        setInvoiceType(doc.data.invoiceType)
        setLines(
          doc.data.lines.map((line) => ({
            key: String(line.salesInvoiceLineId),
            itemId: line.itemId,
            warehouseId: line.warehouseId,
            qty: line.qty,
            freeQty: line.freeQty,
            unitPrice: line.unitPrice,
            allowManualPriceOverride: true,
            discountMode: line.discountMode,
            discountPct: line.discountPct,
            discountAmount: line.discountAmount,
            discountValue: 0,
            taxPct: line.taxPct,
            isFreeIssue: line.isFreeIssue,
            parentLineId: line.parentLineId,
          }))
        )
      })
      .catch((err) => setError(errorMessage(err)))
  }, [invoiceId, resolvedParams.id])

  useEffect(() => {
    if (!invoice || invoice.status !== "Draft") {
      setPostingCheck(null)
      return
    }
    salesApi
      .checkInvoicePosting(invoiceId)
      .then((result) => setPostingCheck(result))
      .catch(() => setPostingCheck(null))
  }, [invoice, invoiceId])

  useEffect(() => {
    if (!invoice || invoice.status !== "Posted") {
      setPayments([])
      return
    }
    salesApi.listInvoicePayments(invoiceId).then(setPayments).catch(() => setPayments([]))
  }, [invoice, invoiceId])

  function handlePaid(_updated: SalesInvoice, payment: SalesInvoicePayment) {
    setInvoice((prev) =>
      prev
        ? {
            ...prev,
            totals: { ...prev.totals, paidAmount: prev.totals.paidAmount + payment.amount, balanceAmount: prev.totals.balanceAmount - payment.amount },
          }
        : prev
    )
    setPayments((prev) => [payment, ...prev])
  }

  const isDraft = invoice?.status === "Draft"
  const customer = useMemo(() => customers.find((c) => c.customerId === invoice?.customerId), [customers, invoice?.customerId])
  const warehouse = useMemo(() => warehouses.find((w) => w.warehouseId === invoice?.warehouseId), [warehouses, invoice?.warehouseId])
  const freeQtyTotal = invoice?.totals.freeQtyTotal ?? 0
  const canPost = invoice?.status === "Draft" && (postingCheck?.canPost ?? true) && !busy && !saving

  function updateLine(key: string, patch: Partial<Line>) {
    setLines((prev) => prev.map((line) => (line.key === key ? { ...line, ...patch } : line)))
  }

  function updateHeaderWarehouse(nextWarehouseId: number | null) {
    setWarehouseId(nextWarehouseId)
    setLines((prev) => prev.map((line) => ({ ...line, warehouseId: nextWarehouseId ?? line.warehouseId })))
  }

  function selectItem(key: string, itemId: number) {
    const item = items.find((candidate) => candidate.itemId === itemId)
    updateLine(key, {
      itemId,
      unitPrice: getSuggestedUnitPrice(items, itemId),
    })
  }

  function resolveLineUnitPrice(line: Line): number | null {
    if (line.unitPrice !== null && line.unitPrice !== undefined) return Number(line.unitPrice)
    return getSuggestedUnitPrice(items, line.itemId)
  }

  function addLine() {
    setLines((prev) => [...prev, { ...blankLine(`line-${Date.now()}`), warehouseId: warehouseId ?? 0 }])
  }

  function removeLine(key: string) {
    setLines((prev) => (prev.length === 1 ? prev : prev.filter((line) => line.key !== key)))
  }

  async function save() {
    if (!customerId || !warehouseId || !etag) return
    if (lines.some((line) => !line.itemId || !line.warehouseId)) {
      setError("Select item, UOM and warehouse for every line.")
      return
    }

    setSaving(true)
    setError(null)
    try {
      const updated = await salesApi.updateInvoice(
        invoiceId,
        {
          customerId,
          warehouseId,
          invoiceType,
            lines: lines.map((line) => ({
              itemId: Number(line.itemId),
              warehouseId: Number(line.warehouseId),
              qty: Number(line.qty),
              freeQty: Number(line.freeQty),
              unitPrice: resolveLineUnitPrice(line),
              allowManualPriceOverride: line.allowManualPriceOverride,
            discountMode: line.discountMode,
            discountPct: Number(line.discountPct),
            discountAmount: Number(line.discountAmount),
            discountValue: Number(line.discountValue),
            taxPct: Number(line.taxPct),
            isFreeIssue: line.isFreeIssue,
            parentLineId: line.parentLineId || null,
          })),
        },
        etag,
      )
      setInvoice(updated.data)
      setEtag(updated.etag)
      toast.success("Invoice saved", updated.data.invoiceNo)
    } catch (err) {
      setError(errorMessage(err))
    } finally {
      setSaving(false)
    }
  }

  async function post() {
    if (!postingCheck?.canPost) {
      setError("Resolve stock shortages before posting this invoice.")
      return
    }
    setBusy("post")
    setError(null)
    try {
      const posted = await salesApi.postInvoice(invoiceId)
      setInvoice(posted)
      toast.success("Invoice posted", posted.invoiceNo)
      router.refresh()
    } catch (err) {
      setError(errorMessage(err))
    } finally {
      setBusy(null)
    }
  }

  async function cancel() {
    setBusy("cancel")
    setError(null)
    try {
      const cancelled = await salesApi.cancelInvoice(invoiceId)
      setInvoice(cancelled)
      toast.success("Invoice cancelled", cancelled.invoiceNo)
      router.refresh()
    } catch (err) {
      setError(errorMessage(err))
    } finally {
      setBusy(null)
    }
  }

  if (error && !invoice) {
    return <div className="rounded-lg border border-destructive/30 bg-destructive/5 p-5 text-destructive">{error}</div>
  }

  if (!invoice) {
    return <div className="rounded-2xl border border-dashed p-8 text-muted-foreground">{error ?? "Invoice data is loading or unavailable."}</div>
  }

  return (
    <div className="mx-auto flex w-full max-w-5xl flex-col gap-6">
      <div className="flex items-center justify-between gap-3 print:hidden">
        <div className="flex items-center gap-3">
          <Link href="/dashboard/sales/invoices" className={cn("inline-flex h-10 w-10 items-center justify-center rounded-full border border-black bg-white text-sm font-medium shadow-sm hover:bg-muted")}>
            <ArrowLeft className="size-4" />
          </Link>
          <div>
            <h1 className="text-2xl font-bold text-foreground">Invoice Details</h1>
            <p className="text-base text-muted-foreground">{invoice.invoiceNo}</p>
          </div>
        </div>
        <Link
          href={`/print/sales/invoices/${invoice.salesInvoiceId}`}
          target="_blank"
          rel="noopener noreferrer"
          className={cn("inline-flex h-10 items-center gap-2 rounded-full border border-black bg-white px-4 text-sm font-medium shadow-sm hover:bg-muted")}
        >
          <Printer className="size-4" />
          Print
        </Link>
      </div>

      {error ? <div className="rounded-lg border border-destructive/30 bg-destructive/5 p-5 text-destructive">{error}</div> : null}

      <section className="bg-white print:bg-white">
        <div className="border-b pb-4">
          <div className="flex flex-col gap-3 md:flex-row md:items-start md:justify-between">
            <div>
            <div className="text-xs font-semibold uppercase tracking-[0.35em] text-muted-foreground">Sales Invoice</div>
            <h2 className="mt-2 text-3xl font-semibold text-foreground">{invoice.invoiceNo}</h2>
            <div className="mt-1 flex flex-wrap items-center gap-2 text-sm text-muted-foreground">
                <span>Status:</span>
                <span className={cn("inline-flex rounded-full border px-2 py-0.5 text-xs font-medium", statusClass(invoice.status))}>{invoice.status}</span>
                <span>Type: {invoice.invoiceType}</span>
                <span>Date: {new Date(invoice.invoiceDate).toLocaleDateString()}</span>
              </div>
            </div>
            <div className="text-sm md:text-right">
              <div className="font-semibold text-foreground">ERP Core Trading</div>
              <div className="text-muted-foreground">Company details are not configured for this invoice view.</div>
            </div>
          </div>
        </div>

        <div className="grid gap-6 py-5 md:grid-cols-3">
          <div>
            <div className="text-xs font-semibold uppercase tracking-wide text-muted-foreground">Bill To</div>
            <div className="mt-2 font-semibold text-foreground">{invoice.customerSnapshotName}</div>
            <div className="text-sm text-muted-foreground">Customer ID: {invoice.customerId}</div>
            {customer?.displayName ? <div className="text-sm text-muted-foreground">Registered name: {customer.displayName}</div> : null}
            {invoice.customerSnapshotTaxNo ? <div className="text-sm text-muted-foreground">Tax No: {invoice.customerSnapshotTaxNo}</div> : null}
          </div>
          <div>
            <div className="text-xs font-semibold uppercase tracking-wide text-muted-foreground">Warehouse</div>
            <div className="mt-2 font-semibold text-foreground">{warehouse?.name ?? `#${invoice.warehouseId}`}</div>
            <div className="text-sm text-muted-foreground">Code: {warehouse?.code ?? invoice.warehouseId}</div>
          </div>
          <div>
            <div className="text-xs font-semibold uppercase tracking-wide text-muted-foreground">Totals</div>
            <div className="mt-2 grid grid-cols-2 gap-2 text-sm">
              <div className="text-muted-foreground">Subtotal</div>
              <div className="text-right font-medium">{money.format(invoice.totals.subtotal)}</div>
              <div className="text-muted-foreground">Discount</div>
              <div className="text-right font-medium">{money.format(invoice.totals.discountTotal)}</div>
              <div className="text-muted-foreground">Free qty</div>
              <div className="text-right font-medium">{freeQtyTotal.toFixed(0)}</div>
              <div className="text-muted-foreground">Tax</div>
              <div className="text-right font-medium">{money.format(invoice.totals.taxTotal)}</div>
              <div className="text-muted-foreground">Net payable</div>
              <div className="text-right font-semibold">{money.format(invoice.totals.netPayable)}</div>
            </div>
          </div>
        </div>

        <div className="overflow-x-auto border-y">
          <table className="w-full text-sm">
            <thead className="bg-secondary/60 text-[11px] uppercase tracking-wide text-muted-foreground">
              <tr>
                <th className="px-4 py-2 text-left font-medium">Item</th>
                <th className="px-4 py-2 text-left font-medium">UOM</th>
                <th className="px-4 py-2 text-right font-medium">Qty</th>
                <th className="px-4 py-2 text-right font-medium">Free</th>
                <th className="px-4 py-2 text-right font-medium">Unit price</th>
                <th className="px-4 py-2 text-right font-medium">Discount</th>
                <th className="px-4 py-2 text-right font-medium">Tax</th>
                <th className="px-4 py-2 text-right font-medium">Line total</th>
              </tr>
            </thead>
            <tbody>
              {invoice.lines.map((line) => (
                <tr key={line.salesInvoiceLineId} className="border-t border-border">
                  <td className="px-4 py-3">
                    <div className="font-medium text-foreground">{line.description}</div>
                    <div className="text-xs text-muted-foreground">SKU {items.find((i) => i.itemId === line.itemId)?.sku ?? `#${line.itemId}`}</div>
                  </td>
                  <td className="px-4 py-3">{baseUomLabel(items, uoms, line.itemId)}</td>
                  <td className="px-4 py-3 text-right">{line.qty.toFixed(0)}</td>
                  <td className="px-4 py-3 text-right">{line.freeQty > 0 ? line.freeQty.toFixed(0) : "—"}</td>
                  <td className="px-4 py-3 text-right">{money.format(line.unitPrice)}</td>
                  <td className="px-4 py-3 text-right">{money.format(line.discountAmount)}</td>
                  <td className="px-4 py-3 text-right">{money.format(line.taxAmount)}</td>
                  <td className="px-4 py-3 text-right font-medium">{money.format(line.lineTotal)}</td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>

        {invoice.lines.some((line) => line.freeQty > 0) ? (
          <div className="py-5">
            <div className="text-sm font-semibold uppercase tracking-wide text-muted-foreground">Free issue summary</div>
            <div className="mt-3 space-y-2">
              {invoice.lines.filter((line) => line.freeQty > 0).map((line) => (
                <div key={line.salesInvoiceLineId} className="flex items-center justify-between text-sm">
                  <div className="text-foreground">{line.description}</div>
                  <div className="text-muted-foreground">Free qty: {line.freeQty.toFixed(0)}</div>
                </div>
              ))}
            </div>
          </div>
        ) : null}

        {invoice.status === "Draft" && postingCheck && !postingCheck.canPost ? (
          <div className="border-t pt-5">
            <div className="rounded-lg border border-amber-200 bg-amber-50 p-4 text-sm text-amber-900">
              <div className="flex flex-col gap-3 md:flex-row md:items-start md:justify-between">
                <div>
                  <div className="font-semibold">Stock shortage detected before posting</div>
                  <div className="mt-1 text-sm">The invoice cannot be posted until every line has enough available stock in the selected warehouse.</div>
                </div>
                <Link
                  href="/dashboard/receiving/grn/new"
                  className="inline-flex h-9 items-center gap-2 self-start rounded-full border border-amber-300 bg-white px-4 text-sm font-medium text-amber-950 shadow-sm hover:bg-amber-100"
                >
                  <ExternalLink className="size-4" />
                  Create GRN
                </Link>
              </div>
              <div className="mt-3 overflow-x-auto">
                <table className="w-full text-sm">
                  <thead className="text-left text-xs uppercase tracking-wide text-amber-900/70">
                    <tr>
                      <th className="py-1 pr-3">Item</th>
                      <th className="py-1 pr-3">Warehouse</th>
                      <th className="py-1 pr-3 text-right">Requested</th>
                      <th className="py-1 pr-3 text-right">Available</th>
                      <th className="py-1 text-right">Short</th>
                    </tr>
                  </thead>
                  <tbody>
                    {postingCheck.issues.map((issue) => (
                      <tr key={issue.salesInvoiceLineId} className="border-t border-amber-200/60">
                        <td className="py-2 pr-3">
                          <div className="font-medium">{issue.itemSku}</div>
                          <div className="text-xs text-amber-900/70">{issue.itemName}{issue.isFreeIssue ? " · free issue" : ""}</div>
                        </td>
                        <td className="py-2 pr-3">{issue.warehouseId}</td>
                        <td className="py-2 pr-3 text-right font-mono tabular-nums">{issue.requestedQty.toFixed(0)}</td>
                        <td className="py-2 pr-3 text-right font-mono tabular-nums">{issue.availableQty.toFixed(0)}</td>
                        <td className="py-2 text-right font-mono tabular-nums">{issue.shortQty.toFixed(0)}</td>
                      </tr>
                    ))}
                  </tbody>
                </table>
              </div>
            </div>
          </div>
        ) : null}

        <div className="border-t pt-5">
          <div className="text-sm font-semibold uppercase tracking-wide text-muted-foreground">Notes</div>
          <p className="mt-2 text-sm text-muted-foreground">Standard invoice template view.</p>
        </div>

        <div className="mt-6 border-t pt-5 print:hidden">
          <div className="mb-3 flex items-center justify-between">
            <h3 className="text-lg font-semibold">Actions</h3>
            <span className="text-sm text-muted-foreground">{isDraft ? "Draft invoice can be edited." : "Only draft invoices are editable."}</span>
          </div>

          {isDraft ? (
            <>
              <div className="mb-4 flex flex-wrap gap-2">
                <button type="button" onClick={addLine} className="inline-flex h-9 items-center gap-2 rounded-full border border-black bg-white px-4 text-sm font-medium shadow-sm hover:bg-muted">
                  <Plus className="size-4" /> Add line
                </button>
                <button type="button" onClick={save} disabled={saving} className="inline-flex h-9 items-center gap-2 rounded-full border border-black bg-white px-4 text-sm font-medium shadow-sm hover:bg-muted disabled:opacity-50">
                  <Save className="size-4" />
                  {saving ? "Saving..." : "Save invoice"}
                </button>
                {postingCheck && !postingCheck.canPost ? (
                  <Link
                    href="/dashboard/receiving/grn/new"
                    className="inline-flex h-9 items-center gap-2 rounded-full border border-amber-300 bg-white px-4 text-sm font-medium text-amber-950 shadow-sm hover:bg-amber-100"
                  >
                    <ExternalLink className="size-4" />
                    Resolve stock in GRN
                  </Link>
                ) : null}
                <button type="button" onClick={post} disabled={!canPost} className="inline-flex h-9 items-center gap-2 rounded-full bg-black px-4 text-sm font-medium text-white shadow-sm hover:bg-black/90 disabled:cursor-not-allowed disabled:opacity-40">
                  <Send className="size-4" />
                  {postingCheck && !postingCheck.canPost ? "Resolve shortages first" : busy === "post" ? "Posting..." : "Post invoice"}
                </button>
                <button type="button" onClick={cancel} disabled={busy !== null} className="inline-flex h-9 items-center gap-2 rounded-full border border-rose-300 bg-rose-50 px-4 text-sm font-medium text-rose-700 shadow-sm hover:bg-rose-100 disabled:opacity-50">
                  <X className="size-4" />
                  {busy === "cancel" ? "Cancelling..." : "Cancel invoice"}
                </button>
              </div>

              <div className="overflow-x-auto border">
                <table className="w-full text-sm">
                  <thead className="bg-secondary/60 text-[11px] uppercase tracking-wide text-muted-foreground">
                    <tr>
                      <th className="px-4 py-2 text-left font-medium">Item</th>
                      <th className="px-4 py-2 text-left font-medium">UOM</th>
                      <th className="px-4 py-2 text-right font-medium">Qty</th>
                      <th className="px-4 py-2 text-right font-medium">Free</th>
                      <th className="px-4 py-2 text-right font-medium">Unit price</th>
                      <th className="px-4 py-2 text-right font-medium">Remove</th>
                    </tr>
                  </thead>
                  <tbody>
                    {lines.map((line) => (
                      <tr key={line.key} className="border-t border-border align-middle">
                        <td className="px-4 py-3 min-w-64">
                          <select
                            value={line.itemId ? String(line.itemId) : ""}
                            onChange={(e) => selectItem(line.key, Number(e.target.value))}
                            className="h-10 w-full rounded-lg border border-input bg-background px-3 text-sm"
                          >
                            <option value="">Select item</option>
                            {items.map((i) => (
                              <option key={i.itemId} value={String(i.itemId)}>
                                {i.sku} - {i.name}
                              </option>
                            ))}
                          </select>
                        </td>
                        <td className="px-4 py-3 min-w-40 text-sm text-muted-foreground">
                          {baseUomLabel(items, uoms, line.itemId)}
                        </td>
                        <td className="px-4 py-3 w-28">
                          <input
                            type="number"
                            min="0"
                            step="1"
                            value={line.qty}
                            onChange={(e) => updateLine(line.key, { qty: Number(e.target.value) || 0 })}
                            className="h-10 w-full rounded-lg border border-input bg-background px-3 text-right font-mono tabular-nums text-sm"
                          />
                        </td>
                        <td className="px-4 py-3 w-28">
                        <input
                          type="number"
                          min="0"
                          step="1"
                          value={line.freeQty}
                          onChange={(e) => updateLine(line.key, { freeQty: Number(e.target.value) || 0 })}
                          className="h-10 w-full rounded-lg border border-input bg-background px-3 text-right font-mono tabular-nums text-sm"
                        />
                      </td>
                        <td className="px-4 py-3 w-32">
                          <input
                            type="number"
                            min="0"
                            step="0.01"
                            value={line.unitPrice ?? ""}
                            onChange={(e) => updateLine(line.key, { unitPrice: e.target.value === "" ? null : Number(e.target.value) })}
                            className="h-10 w-full rounded-lg border border-input bg-background px-3 text-right font-mono tabular-nums text-sm"
                          />
                          <div className="mt-1 text-[11px] text-muted-foreground">
                            {getSuggestedUnitPrice(items, line.itemId) !== null
                              ? `Suggested: ${money.format(getSuggestedUnitPrice(items, line.itemId) ?? 0)}`
                              : "No price suggestion available"}
                          </div>
                        </td>
                        <td className="px-4 py-3 w-24 text-right">
                    <button
                      type="button"
                      onClick={() => removeLine(line.key)}
                      disabled={lines.length === 1}
                            className="inline-flex h-9 w-9 items-center justify-center rounded-full border border-black bg-white text-sm font-medium shadow-sm hover:bg-muted disabled:opacity-50"
                          >
                            <Minus className="size-4" />
                          </button>
                        </td>
                      </tr>
                    ))}
                  </tbody>
                </table>
              </div>

              <div className="mt-5 grid gap-4 md:grid-cols-3">
                <div className="space-y-1.5">
                  <Label className="text-xs">Customer</Label>
                  <select
                    value={customerId ? String(customerId) : ""}
                    onChange={(e) => setCustomerId(e.target.value ? Number(e.target.value) : null)}
                    className="h-10 w-full rounded-lg border border-input bg-background px-3 text-sm"
                  >
                    <option value="">Select customer</option>
                    {customers.map((c) => (
                      <option key={c.customerId} value={String(c.customerId)}>
                        {c.customerCode} - {c.displayName ?? c.name}
                      </option>
                    ))}
                  </select>
                </div>
                <div className="space-y-1.5">
                  <Label className="text-xs">Warehouse</Label>
                  <select
                    value={warehouseId ? String(warehouseId) : ""}
                    onChange={(e) => updateHeaderWarehouse(e.target.value ? Number(e.target.value) : null)}
                    className="h-10 w-full rounded-lg border border-input bg-background px-3 text-sm"
                  >
                    <option value="">Select warehouse</option>
                    {warehouses.map((w) => (
                      <option key={w.warehouseId} value={String(w.warehouseId)}>
                        {w.code} - {w.name}
                      </option>
                    ))}
                  </select>
                </div>
                <div className="space-y-1.5">
                  <Label className="text-xs">Invoice type</Label>
                  <select
                    value={invoiceType}
                    onChange={(e) => setInvoiceType(e.target.value as SalesInvoiceType)}
                    className="h-10 w-full rounded-lg border border-input bg-background px-3 text-sm"
                  >
                    <option value="B2B">B2B</option>
                    <option value="B2C">B2C</option>
                    <option value="Cash">Cash</option>
                    <option value="Credit">Credit</option>
                  </select>
                </div>
              </div>
              <div className="mt-5 flex justify-end">
                <button
                  type="button"
                  onClick={post}
                  disabled={!canPost}
                  className="inline-flex h-10 items-center gap-2 rounded-full bg-black px-5 text-sm font-medium text-white shadow-sm hover:bg-black/90 disabled:cursor-not-allowed disabled:opacity-40"
                >
                  <Send className="size-4" />
                  {postingCheck && !postingCheck.canPost ? "Resolve shortages first" : busy === "post" ? "Posting..." : "Post invoice"}
                </button>
              </div>
            </>
          ) : (
            <div className="flex flex-col gap-3 rounded-2xl border border-dashed p-4 text-sm text-muted-foreground sm:flex-row sm:items-center sm:justify-between">
              <span>This invoice is {invoice.status.toLowerCase()} and cannot be edited.</span>
              {invoice.status === "Posted" ? (
                <div className="flex flex-wrap items-center gap-2">
                  <Link
                    href={`/dashboard/sales/sales-returns/new?invoiceId=${invoice.salesInvoiceId}`}
                    className="inline-flex h-9 items-center gap-2 self-start rounded-full border border-black bg-white px-4 text-sm font-medium text-foreground shadow-sm hover:bg-muted sm:self-auto"
                  >
                    <Undo2 className="size-4" />
                    Return items
                  </Link>
                  <Button size="sm" onClick={() => setPayDialogOpen(true)} disabled={invoice.totals.balanceAmount <= 0}>
                    {invoice.totals.balanceAmount <= 0 ? "Fully paid" : "Record payment"}
                  </Button>
                </div>
              ) : null}
            </div>
          )}

          {invoice.status === "Posted" && (
            <div className="mt-5 flex flex-col gap-2 rounded-2xl border border-border p-4">
              <div className="flex flex-wrap items-center justify-between gap-2 text-sm">
                <span className="font-semibold text-foreground">Payment status</span>
                <span className="text-muted-foreground">
                  Paid {money.format(invoice.totals.paidAmount)} of {money.format(invoice.totals.netPayable)} — balance {money.format(invoice.totals.balanceAmount)}
                  {invoice.glJournalNo ? ` · GL journal ${invoice.glJournalNo}` : ""}
                </span>
              </div>
              {payments.length > 0 && (
                <div className="overflow-x-auto">
                  <table className="w-full text-sm">
                    <thead className="text-left text-xs uppercase tracking-wide text-muted-foreground">
                      <tr>
                        <th className="py-1 pr-3">Date</th>
                        <th className="py-1 pr-3">Account</th>
                        <th className="py-1 pr-3">Reference</th>
                        <th className="py-1 pr-3">GL journal</th>
                        <th className="py-1 text-right">Amount</th>
                      </tr>
                    </thead>
                    <tbody>
                      {payments.map((p) => (
                        <tr key={p.salesInvoicePaymentId} className="border-t border-border">
                          <td className="py-2 pr-3">{new Date(p.paymentDate).toLocaleString()}</td>
                          <td className="py-2 pr-3">{p.bankAccountName}</td>
                          <td className="py-2 pr-3">{p.reference ?? "—"}</td>
                          <td className="py-2 pr-3">{p.glJournalNo ?? "—"}</td>
                          <td className="py-2 text-right font-mono tabular-nums">{money.format(p.amount)}</td>
                        </tr>
                      ))}
                    </tbody>
                  </table>
                </div>
              )}
            </div>
          )}
        </div>
      </section>

      <SalesInvoicePaymentDialog invoice={invoice} open={payDialogOpen} onOpenChange={setPayDialogOpen} onPaid={handlePaid} />
    </div>
  )
}
