"use client"

import { useEffect, useMemo, useState } from "react"
import Link from "next/link"
import { ArrowLeft, Eraser, Pencil, Plus, Save, Trash2, X } from "lucide-react"

import { Button, buttonVariants } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import { Combobox } from "@/components/ui/combobox"
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"
import { cn } from "@/lib/utils"
import { errorMessage } from "@/lib/error-map"
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 { usersApi } from "@/lib/api/users"
import { toast } from "@/components/ui/toast"
import { Customer } from "@/types/customers"
import { ItemListItem, Uom, Warehouse } from "@/types/master-data"
import { ManagedUser } from "@/types/users"
import { CreateSalesSlipLineRequest, CreateSalesSlipRequest } from "@/types/sales"

type Line = CreateSalesSlipLineRequest & { key: string }

type FreeIssueRow = {
  salesSlipId: number
  slipNo: string
  status: string
  etag: string
  warehouseName: string
  itemName: string
  itemSku: string
  uomName: string
  qty: number
  freeQty: number
}

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

export default function NewFreeIssuePage() {
  const [customers, setCustomers] = useState<Customer[]>([])
  const [items, setItems] = useState<ItemListItem[]>([])
  const [uoms, setUoms] = useState<Uom[]>([])
  const [warehouses, setWarehouses] = useState<Warehouse[]>([])
  const [users, setUsers] = useState<ManagedUser[]>([])
  const [customerId, setCustomerId] = useState<number | null>(null)
  const [warehouseId, setWarehouseId] = useState<number | null>(null)
  const [cashierUserId, setCashierUserId] = useState<number | null>(null)
  const [lines, setLines] = useState<Line[]>([blankLine("line-1")])
  const [rows, setRows] = useState<FreeIssueRow[]>([])
  const [editingRowId, setEditingRowId] = useState<number | null>(null)
  const [editingLines, setEditingLines] = useState<Line[]>([])
  const [loading, setLoading] = useState(true)
  const [saving, setSaving] = useState(false)
  const [error, setError] = useState<string | null>(null)

  async function refreshRows() {
    const list = await salesApi.listFreeIssues({ pageSize: 50 })
    const details = await Promise.all(
      list.items.map(async (summary) => {
        const detail = await salesApi.getFreeIssue(summary.salesSlipId)
        const firstLine = detail.data.lines[0]
        const item = items.find((x) => x.itemId === firstLine?.itemId)
        const warehouse = warehouses.find((x) => x.warehouseId === detail.data.warehouseId)
        return {
          salesSlipId: detail.data.salesSlipId,
          slipNo: detail.data.slipNo,
          status: detail.data.status,
          etag: detail.etag ?? "",
          warehouseName: warehouse?.name ?? `Warehouse ${detail.data.warehouseId}`,
          itemName: item?.name ?? firstLine?.description ?? "—",
          itemSku: item?.sku ?? `SKU-${firstLine?.itemId ?? 0}`,
          uomName: baseUomLabel(items, uoms, firstLine?.itemId),
          qty: firstLine?.qty ?? 0,
          freeQty: firstLine?.freeQty ?? 0,
        } satisfies FreeIssueRow
      }),
    )
    setRows(details.filter((row) => row.status !== "Cancelled"))
  }

  useEffect(() => {
    Promise.all([
      customersApi.list({ pageSize: 200 }),
      itemsApi.list({ pageSize: 200 }),
      uomsApi.list({ pageSize: 200 }),
      warehousesApi.list({ pageSize: 200 }),
      usersApi.list({ pageSize: 200 }),
    ])
      .then(async ([cust, itemRes, uomRes, whRes, userRes]) => {
        setCustomers(cust.items)
        setItems(itemRes.items)
        setUoms(uomRes.items)
        setWarehouses(whRes.items)
        setUsers(userRes.items)
        setCustomerId(cust.items[0]?.customerId ?? null)
        setWarehouseId(whRes.items[0]?.warehouseId ?? null)
        setCashierUserId(userRes.items[0]?.userId ?? null)
        setLines([
          {
            ...blankLine("line-1"),
            itemId: itemRes.items[0]?.itemId ?? 0,
            warehouseId: whRes.items[0]?.warehouseId ?? 0,
          },
        ])
        await refreshRows()
      })
      .catch((err) => setError(errorMessage(err)))
      .finally(() => setLoading(false))
  }, [])

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

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

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

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

  function clearAllLines() {
    setLines([blankLine("line-1")])
  }

  const itemOptions = useMemo(
    () => items.map((i) => ({ value: i.itemId, label: `${i.sku} - ${i.name}` })),
    [items]
  )

  function selectItem(key: string, itemId: number) {
    updateLine(key, { itemId })
  }

  function selectEditingItem(key: string, itemId: number) {
    updateEditingLine(key, { itemId })
  }

  async function submit() {
    const activeLines = editingRowId ? editingLines : lines
    if (!customerId || !warehouseId || !cashierUserId) return setError("Select customer, warehouse, and cashier.")
    if (activeLines.some((line) => !line.itemId)) return setError("Select an item for every line.")
    if (activeLines.some((line) => !line.warehouseId)) return setError("Select a warehouse for every line.")

    setSaving(true)
    setError(null)
    try {
      const payload: CreateSalesSlipRequest = {
        customerId,
        warehouseId,
        cashierUserId,
        lines: activeLines.map((line) => ({
          itemId: Number(line.itemId),
          warehouseId: Number(line.warehouseId),
          qty: Number(line.qty),
          freeQty: Number(line.freeQty),
          unitPrice: line.unitPrice === null ? null : Number(line.unitPrice),
          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,
        })),
      }

      if (editingRowId) {
        const latest = await salesApi.getFreeIssue(editingRowId)
        if (!latest.etag) throw new Error("Missing ETag for free issue update.")
        await salesApi.updateFreeIssue(editingRowId, payload, latest.etag)
        toast.success("Free issue updated")
        setEditingRowId(null)
        setEditingLines([])
      } else {
        const created = await salesApi.createFreeIssue(payload)
        toast.success("Free issue created", created.data.slipNo)
      }

      setLines([blankLine("line-1")])
      await refreshRows()
    } catch (err) {
      setError(errorMessage(err))
    } finally {
      setSaving(false)
    }
  }

  async function startEdit(row: FreeIssueRow) {
    try {
      const detail = await salesApi.getFreeIssue(row.salesSlipId)
      const detailLine = detail.data.lines[0]
      setEditingRowId(row.salesSlipId)
      setCustomerId(detail.data.customerId)
      setWarehouseId(detail.data.warehouseId)
      setCashierUserId(detail.data.cashierUserId)
      setEditingLines([
        {
          key: "edit-line-1",
          itemId: detailLine?.itemId ?? 0,
          warehouseId: detailLine?.warehouseId ?? detail.data.warehouseId,
          qty: detailLine?.qty ?? 1,
          freeQty: detailLine?.freeQty ?? 0,
          unitPrice: detailLine?.unitPrice ?? null,
          allowManualPriceOverride: true,
          discountMode: detailLine?.discountMode ?? "Percentage",
          discountPct: detailLine?.discountPct ?? 0,
          discountAmount: detailLine?.discountAmount ?? 0,
          discountValue: 0,
          taxPct: detailLine?.taxPct ?? 0,
          isFreeIssue: detailLine?.isFreeIssue ?? false,
          parentLineId: detailLine?.parentLineId ?? null,
        },
      ])
    } catch (err) {
      setError(errorMessage(err))
    }
  }

  function cancelEdit() {
    setEditingRowId(null)
    setEditingLines([])
  }

  async function deleteRow(row: FreeIssueRow) {
    if (row.status !== "Draft") return
    try {
      await salesApi.cancelFreeIssue(row.salesSlipId)
      toast.success("Free issue cancelled", row.slipNo)
      if (editingRowId === row.salesSlipId) cancelEdit()
      await refreshRows()
    } catch (err) {
      setError(errorMessage(err))
    }
  }

  if (loading) {
    return <div className="rounded-2xl border border-border bg-card p-8 text-muted-foreground shadow-[var(--shadow-panel)]">Loading masters...</div>
  }

  const activeLines = editingRowId ? editingLines : lines

  return (
    <div className="flex flex-col gap-6">
      <div className="flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between">
        <div className="flex items-center gap-3">
          <Link href="/dashboard/sales" className={cn(buttonVariants({ variant: "outline", size: "icon" }))}>
            <ArrowLeft className="size-4" />
          </Link>
          <div>
            <h1 className="text-2xl font-bold text-foreground">Free Issues</h1>
            <p className="text-base text-muted-foreground">Create and manage free-issue sales slips from the backend.</p>
          </div>
        </div>
        <Button size="sm" onClick={submit} disabled={saving}>
          <Save className="size-4" /> {saving ? "Saving..." : editingRowId ? "Update free issue" : "Create free issue"}
        </Button>
      </div>

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

      {editingRowId ? (
        <section className="rounded-2xl border border-sky-200 bg-sky-50 shadow-[var(--shadow-panel)]">
          <div className="flex items-center justify-between border-b border-sky-200 px-4 py-3">
            <h2 className="text-sm font-semibold text-sky-900">Inline edit free issue</h2>
            <Button type="button" variant="outline" size="sm" onClick={cancelEdit}>
              <X className="size-4" /> Cancel edit
            </Button>
          </div>
          <div className="overflow-x-auto">
            <Table className="text-sm">
              <TableHeader>
                <TableRow>
                  <TableHead className="h-12 px-4 text-sm">ID</TableHead>
                  <TableHead className="h-12 px-4 text-sm">Item</TableHead>
                  <TableHead className="h-12 px-4 text-sm">UOM</TableHead>
                  <TableHead className="h-12 px-4 text-sm text-right">Qty</TableHead>
                  <TableHead className="h-12 px-4 text-sm text-right">Free</TableHead>
                  <TableHead className="h-12 px-4 text-sm" />
                </TableRow>
              </TableHeader>
              <TableBody>
                {activeLines.map((line, idx) => (
                  <TableRow key={line.key} className="align-middle">
                    <TableCell className="px-4 py-2 text-xs text-muted-foreground">{idx + 1}</TableCell>
                    <TableCell className="px-4 py-2 min-w-80">
                      <Combobox
                        items={itemOptions}
                        value={line.itemId || null}
                        onValueChange={(v) => selectEditingItem(line.key, v ?? 0)}
                        placeholder="Search item…"
                      />
                    </TableCell>
                    <TableCell className="px-4 py-2 min-w-44 text-sm text-muted-foreground">
                      {baseUomLabel(items, uoms, line.itemId)}
                    </TableCell>
                    <TableCell className="px-4 py-2">
                      <Input type="number" min="0" step="1" value={line.qty} onChange={(e) => updateEditingLine(line.key, { qty: Number(e.target.value) })} className="h-9 w-24 text-right font-mono text-sm tabular-nums" />
                    </TableCell>
                    <TableCell className="px-4 py-2">
                      <Input type="number" min="0" step="1" value={line.freeQty} onChange={(e) => updateEditingLine(line.key, { freeQty: Number(e.target.value) })} className="h-9 w-24 text-right font-mono text-sm tabular-nums" />
                    </TableCell>
                    <TableCell className="px-4 py-2 text-right text-xs text-muted-foreground">editing</TableCell>
                  </TableRow>
                ))}
              </TableBody>
            </Table>
          </div>
        </section>
      ) : (
        <section className="rounded-2xl border border-border bg-card shadow-[var(--shadow-panel)]">
          <div className="flex items-center justify-between border-b border-border px-4 py-3">
            <h2 className="text-sm font-semibold">Free issue lines</h2>
            <div className="flex items-center gap-2">
              <Button
                type="button"
                variant="outline"
                size="sm"
                onClick={clearAllLines}
                disabled={lines.length === 1 && !lines[0].itemId}
              >
                <Eraser className="size-4" /> Clear all lines
              </Button>
              <Button type="button" variant="outline" size="sm" onClick={addLine}>
                <Plus className="size-4" /> Add line
              </Button>
            </div>
          </div>
          <div className="overflow-x-auto">
            <Table className="text-sm">
              <TableHeader>
                <TableRow>
                  <TableHead className="h-12 px-4 text-sm">ID</TableHead>
                  <TableHead className="h-12 px-4 text-sm">Item</TableHead>
                  <TableHead className="h-12 px-4 text-sm">UOM</TableHead>
                  <TableHead className="h-12 px-4 text-sm text-right">Qty</TableHead>
                  <TableHead className="h-12 px-4 text-sm text-right">Free</TableHead>
                  <TableHead className="h-12 px-4 text-sm" />
                </TableRow>
              </TableHeader>
              <TableBody>
                {lines.map((line, idx) => (
                  <TableRow key={line.key} className="align-middle">
                    <TableCell className="px-4 py-2 text-xs text-muted-foreground">{idx + 1}</TableCell>
                    <TableCell className="px-4 py-2 min-w-80">
                      <Combobox
                        items={itemOptions}
                        value={line.itemId || null}
                        onValueChange={(v) => selectItem(line.key, v ?? 0)}
                        placeholder="Search item…"
                      />
                    </TableCell>
                    <TableCell className="px-4 py-2 min-w-44">
                      {baseUomLabel(items, uoms, line.itemId)}
                    </TableCell>
                    <TableCell className="px-4 py-2">
                      <Input type="number" min="0" step="1" value={line.qty} onChange={(e) => updateLine(line.key, { qty: Number(e.target.value) })} className="h-9 w-24 text-right font-mono text-sm tabular-nums" />
                    </TableCell>
                    <TableCell className="px-4 py-2">
                      <Input type="number" min="0" step="1" value={line.freeQty} onChange={(e) => updateLine(line.key, { freeQty: Number(e.target.value) })} className="h-9 w-24 text-right font-mono text-sm tabular-nums" />
                    </TableCell>
                    <TableCell className="px-4 py-2 text-right">
                      <Button variant="ghost" size="icon" className="size-8 text-muted-foreground" onClick={() => removeLine(line.key)} disabled={lines.length === 1}>
                        <Trash2 className="size-4" />
                      </Button>
                    </TableCell>
                  </TableRow>
                ))}
              </TableBody>
            </Table>
          </div>
        </section>
      )}

      <section className="rounded-2xl border border-border bg-card p-4 shadow-[var(--shadow-panel)]">
        <div className="flex items-center justify-between">
          <div>
            <h3 className="text-sm font-semibold">Created free issues</h3>
            <p className="mt-1 text-xs text-muted-foreground">Persisted backend records with draft-only cancellation.</p>
          </div>
          <Button variant="outline" size="sm" onClick={refreshRows}>
            Refresh
          </Button>
        </div>
        <div className="mt-3 overflow-x-auto">
          <Table className="text-sm">
            <TableHeader>
              <TableRow>
                <TableHead className="h-12 px-4 text-sm">Promotion</TableHead>
                <TableHead className="h-12 px-4 text-sm">Warehouse</TableHead>
                <TableHead className="h-12 px-4 text-sm">Product</TableHead>
                <TableHead className="h-12 px-4 text-sm text-right">Qty</TableHead>
                <TableHead className="h-12 px-4 text-sm text-right">Free</TableHead>
                <TableHead className="h-12 px-4 text-sm text-right">Actions</TableHead>
              </TableRow>
            </TableHeader>
            <TableBody>
              {rows.length > 0 ? (
                rows.map((row) => (
                  <TableRow key={row.salesSlipId} className="hover:bg-muted/40">
                    <TableCell className="px-4 py-3.5">
                      <div className="font-medium">Buy {row.qty} Get {row.freeQty || 0}</div>
                      <div className="text-xs text-muted-foreground">{row.slipNo}</div>
                    </TableCell>
                    <TableCell className="px-4 py-3.5">{row.warehouseName}</TableCell>
                    <TableCell className="px-4 py-3.5 min-w-80">
                      <div className="font-medium">{row.itemName}</div>
                      <div className="text-xs text-muted-foreground">{row.itemSku} · {row.uomName}</div>
                    </TableCell>
                    <TableCell className="px-4 py-3.5 text-right font-mono tabular-nums">{row.qty}</TableCell>
                    <TableCell className="px-4 py-3.5 text-right font-mono tabular-nums">{row.freeQty}</TableCell>
                    <TableCell className="px-4 py-3.5">
                      <div className="flex justify-end gap-1.5">
                        <button
                          type="button"
                          onClick={() => startEdit(row)}
                          className="inline-flex h-7 items-center rounded-full border border-sky-200 bg-sky-50 px-2 text-xs text-sky-700 hover:bg-sky-100 hover:text-sky-800"
                        >
                          <Pencil className="mr-1 size-3.5" />
                          Edit
                        </button>
                        {row.status === "Draft" ? (
                          <button
                            type="button"
                            onClick={() => deleteRow(row)}
                            className="inline-flex h-7 items-center rounded-full border border-rose-200 bg-rose-50 px-2 text-xs text-rose-700 hover:bg-rose-100 hover:text-rose-800"
                          >
                            <Trash2 className="mr-1 size-3.5" />
                            Delete
                          </button>
                        ) : null}
                      </div>
                    </TableCell>
                  </TableRow>
                ))
              ) : (
                <TableRow>
                  <TableCell colSpan={6} className="px-4 py-8 text-center text-sm text-muted-foreground">
                    No free issues created yet.
                  </TableCell>
                </TableRow>
              )}
            </TableBody>
          </Table>
        </div>
      </section>
    </div>
  )
}
