"use client"

import { useEffect, useMemo, useState } from "react"
import Link from "next/link"
import { useParams, useRouter } from "next/navigation"
import { ArrowLeft, CheckCircle2, Edit, ExternalLink, Minus, Plus, Printer, Save, XCircle } from "lucide-react"

import { bundleApi } from "@/lib/api/bundles"
import { itemsApi } from "@/lib/api/items"
import { uomsApi } from "@/lib/api/uoms"
import { baseUomLabel } from "@/lib/uom-label"
import { errorMessage } from "@/lib/error-map"
import { Button, buttonVariants } from "@/components/ui/button"
import { Badge } from "@/components/ui/badge"
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"
import { cn } from "@/lib/utils"
import { BundleSale, BundleSaleTemplate, BundleSaleTemplateSummary, BundleSaleTemplateLine, UpdateBundleSaleRequest } from "@/types/bundles"
import { customersApi } from "@/lib/api/customers"
import { warehousesApi } from "@/lib/api/warehouses"
import { usersApi } from "@/lib/api/users"
import { Customer } from "@/types/customers"
import { ItemListItem, Uom, Warehouse } from "@/types/master-data"
import { ManagedUser } from "@/types/users"

type EditableLine = BundleSaleTemplateLine & { key: string }

const createBlankLine = (templateLine?: BundleSaleTemplateLine): EditableLine => ({
  key: crypto.randomUUID(),
  bundleSaleTemplateLineId: templateLine?.bundleSaleTemplateLineId ?? 0,
  itemId: templateLine?.itemId ?? 0,
  warehouseId: templateLine?.warehouseId ?? 0,
  qty: templateLine?.qty ?? 1,
  unitPrice: templateLine?.unitPrice ?? 0,
  includeInBundle: templateLine?.includeInBundle ?? true,
  sortOrder: templateLine?.sortOrder ?? 0,
})

function statusClass(status: BundleSale["status"]) {
  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 BundleSaleDetailPage() {
  const router = useRouter()
  const params = useParams<{ id: string }>()
  const bundleSaleId = Number(params.id)
  const [bundle, setBundle] = useState<BundleSale | null>(null)
  const [editing, setEditing] = useState(false)
  const [templates, setTemplates] = useState<BundleSaleTemplateSummary[]>([])
  const [template, setTemplate] = useState<BundleSaleTemplate | null>(null)
  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 [templateId, setTemplateId] = useState<number | null>(null)
  const [bundleName, setBundleName] = useState("")
  const [bundlePrice, setBundlePrice] = useState(0)
  const [allowPriceOverride, setAllowPriceOverride] = useState(false)
  const [lines, setLines] = useState<EditableLine[]>([])
  const [error, setError] = useState<string | null>(null)
  const [busy, setBusy] = useState(false)

  useEffect(() => {
    if (!Number.isFinite(bundleSaleId)) {
      setError(`Invalid bundle id '${params.id}'.`)
      return
    }
    Promise.all([
      bundleApi.getBundle(bundleSaleId),
      bundleApi.listTemplates({ pageSize: 200 }),
      customersApi.list({ pageSize: 200 }),
      itemsApi.list({ pageSize: 200 }),
      uomsApi.list({ pageSize: 200 }),
      warehousesApi.list({ pageSize: 200 }),
      usersApi.list({ pageSize: 200 }),
    ])
      .then(([bundleRes, templateRes, custRes, itemRes, uomRes, whRes, userRes]) => {
        const data = bundleRes
        setBundle(data)
        setTemplates(templateRes.items)
        setCustomers(custRes.items)
        setItems(itemRes.items)
        setUoms(uomRes.items)
        setWarehouses(whRes.items)
        setUsers(userRes.items)
        setCustomerId(data.customerId)
        setWarehouseId(data.warehouseId)
        setCashierUserId(data.cashierUserId)
        setTemplateId(data.bundleSaleTemplateId)
        setBundleName(data.bundleName)
        setBundlePrice(data.bundlePrice)
        setLines(
          data.lines.map((line) => ({
            key: `${line.bundleSaleLineId}`,
            bundleSaleTemplateLineId: line.bundleSaleLineId,
            itemId: line.itemId,
            warehouseId: line.warehouseId,
            qty: line.qty,
            unitPrice: line.unitPrice,
            includeInBundle: line.includeInBundle,
            sortOrder: line.bundleSaleLineId,
          }))
        )
      })
      .catch((err) => setError(errorMessage(err)))
  }, [bundleSaleId, params.id, items])

  useEffect(() => {
    if (!templateId) return
    bundleApi.getTemplate(templateId).then(setTemplate).catch((err) => setError(errorMessage(err)))
  }, [templateId])

  const templateLabel = useMemo(() => templates.find((t) => t.bundleSaleTemplateId === templateId)?.templateName ?? "Template", [templates, templateId])
  const componentSubtotal = useMemo(() => lines.reduce((sum, line) => sum + Number(line.qty || 0) * Number(line.unitPrice || 0), 0), [lines])
  const isDraft = bundle?.status === "Draft"
  const canEdit = isDraft

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

  function addLine() {
    const source = template?.lines[0]
    if (!source) return
    setLines((prev) => [...prev, createBlankLine(source)])
  }

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

  async function saveBundle() {
    if (!bundle || !customerId || !warehouseId || !cashierUserId || !templateId) return
    setBusy(true)
    setError(null)
    try {
      const request: UpdateBundleSaleRequest = {
        customerId,
        warehouseId,
        cashierUserId,
        bundleSaleTemplateId: templateId,
        bundleName,
        bundlePrice,
        allowPriceOverride,
        lines: lines.map(({ key, ...line }) => line),
      }
      const res = await bundleApi.updateBundle(bundle.bundleSaleId, request)
      setBundle(res)
      setEditing(false)
      router.refresh()
    } catch (err) {
      setError(errorMessage(err))
    } finally {
      setBusy(false)
    }
  }

  async function postBundle() {
    if (!bundle) return
    setBusy(true)
    setError(null)
    try {
      const check = await bundleApi.checkBundlePosting(bundle.bundleSaleId)
      if (!check.canPost) {
        setError("Resolve stock shortages before posting this bundle.")
        return
      }
      const updated = await bundleApi.postBundle(bundle.bundleSaleId)
      setBundle({ ...bundle, ...updated })
    } catch (err) {
      setError(errorMessage(err))
    } finally {
      setBusy(false)
    }
  }

  const shortageIssues = bundle && bundle.status === "Draft"
    ? bundle.lines
        .filter((line) => line.includeInBundle)
        .filter((line) => Number(line.qty || 0) > 0)
        .map((line) => ({
          bundleSaleLineId: line.bundleSaleLineId,
          itemId: line.itemId,
          itemSku: items.find((item) => item.itemId === line.itemId)?.sku ?? `#${line.itemId}`,
          itemName: items.find((item) => item.itemId === line.itemId)?.name ?? line.itemId.toString(),
          warehouseId: line.warehouseId,
          requestedQty: line.qty,
        }))
      : []

  async function cancelBundle() {
    if (!bundle) return
    setBusy(true)
    setError(null)
    try {
      const updated = await bundleApi.cancelBundle(bundle.bundleSaleId)
      setBundle({ ...bundle, ...updated })
    } catch (err) {
      setError(errorMessage(err))
    } finally {
      setBusy(false)
    }
  }

  if (error && !bundle) return <div className="rounded-lg border border-destructive/30 bg-destructive/5 p-5 text-base text-destructive">{error}</div>
  if (!bundle) return <div className="rounded-2xl border border-dashed p-8 text-muted-foreground">Loading bundle sale...</div>

  const printHref = `/print/sales/bundles/${bundle.bundleSaleId}`

  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/bundles" className={cn(buttonVariants({ variant: "outline", size: "icon" }))}>
            <ArrowLeft className="size-4" />
          </Link>
          <div>
            <h1 className="text-2xl font-bold text-foreground">{bundle.bundleNo}</h1>
            <p className="text-base text-muted-foreground">{bundle.bundleName}</p>
          </div>
        </div>
        <div className="flex flex-wrap gap-2">
          <Link href={printHref} target="_blank" rel="noopener noreferrer" className={cn(buttonVariants({ variant: "outline", size: "lg" }))}>
            <Printer className="size-4" />
            Print
          </Link>
          {canEdit ? (
            editing ? (
              <Button variant="outline" size="lg" onClick={saveBundle} disabled={busy}>
                <Save className="size-4" />
                Save
              </Button>
            ) : (
              <Button variant="outline" size="lg" onClick={() => setEditing(true)} disabled={!isDraft}>
                <Edit className="size-4" />
                Edit
              </Button>
            )
          ) : null}
          {isDraft ? (
            <>
              <Button variant="outline" size="lg" onClick={postBundle} disabled={busy}>
                <CheckCircle2 className="size-4" />
                Post
              </Button>
              <Button variant="outline" size="lg" onClick={cancelBundle} disabled={busy}>
                <XCircle className="size-4" />
                Cancel
              </Button>
            </>
          ) : null}
        </div>
      </div>

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

      {bundle.status === "Draft" && shortageIssues.length > 0 ? (
        <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">This bundle cannot be posted until every included component 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>
                </tr>
              </thead>
              <tbody>
                {shortageIssues.map((issue) => (
                  <tr key={issue.bundleSaleLineId} 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}</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>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        </div>
      ) : null}

      <section className="rounded-2xl border bg-card p-4 shadow-sm">
        <div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-3">
          <div className="space-y-1.5">
            <Label>Customer</Label>
            <Select value={customerId ? String(customerId) : "all"} onValueChange={(v) => setCustomerId(v === "all" ? null : Number(v))} disabled={!editing || !isDraft}>
              <SelectTrigger><SelectValue placeholder="Customer" /></SelectTrigger>
              <SelectContent>{customers.map((c) => <SelectItem key={c.customerId} value={String(c.customerId)}>{c.customerCode} - {c.displayName ?? c.name}</SelectItem>)}</SelectContent>
            </Select>
          </div>
          <div className="space-y-1.5">
            <Label>Warehouse</Label>
            <Select value={warehouseId ? String(warehouseId) : "all"} onValueChange={(v) => setWarehouseId(v === "all" ? null : Number(v))} disabled={!editing || !isDraft}>
              <SelectTrigger><SelectValue placeholder="Warehouse" /></SelectTrigger>
              <SelectContent>{warehouses.map((w) => <SelectItem key={w.warehouseId} value={String(w.warehouseId)}>{w.code} - {w.name}</SelectItem>)}</SelectContent>
            </Select>
          </div>
          <div className="space-y-1.5">
            <Label>Cashier</Label>
            <Select value={cashierUserId ? String(cashierUserId) : "all"} onValueChange={(v) => setCashierUserId(v === "all" ? null : Number(v))} disabled={!editing || !isDraft}>
              <SelectTrigger><SelectValue placeholder="Cashier" /></SelectTrigger>
              <SelectContent>{users.map((u) => <SelectItem key={u.userId} value={String(u.userId)}>{u.displayName}</SelectItem>)}</SelectContent>
            </Select>
          </div>
          <div className="space-y-1.5">
            <Label>Template</Label>
            <Select value={templateId ? String(templateId) : "all"} onValueChange={(v) => setTemplateId(v === "all" ? null : Number(v))} disabled={!editing || !isDraft}>
              <SelectTrigger><SelectValue placeholder={templateLabel} /></SelectTrigger>
              <SelectContent>{templates.map((t) => <SelectItem key={t.bundleSaleTemplateId} value={String(t.bundleSaleTemplateId)}>{t.templateCode} - {t.templateName}</SelectItem>)}</SelectContent>
            </Select>
          </div>
          <div className="space-y-1.5">
            <Label>Bundle name</Label>
            <Input value={bundleName} onChange={(e) => setBundleName(e.target.value)} disabled={!editing || !isDraft} />
          </div>
          <div className="space-y-1.5">
            <Label>Bundle price</Label>
            <Input type="number" min="0" step="0.01" value={bundlePrice} onChange={(e) => setBundlePrice(Number(e.target.value))} disabled={!editing || !isDraft} />
          </div>
        </div>
      </section>

      <section className="rounded-2xl border bg-card shadow-sm">
        <div className="flex items-center justify-between border-b px-4 py-3">
          <div>
            <h2 className="text-sm font-semibold">Component breakdown</h2>
            <p className="text-xs text-muted-foreground">{editing ? "Edit the component lines and save." : "Read-only until you enter edit mode."}</p>
          </div>
          {editing && isDraft ? <Button type="button" variant="outline" size="sm" onClick={addLine}><Plus className="size-4" /> Add line</Button> : <Badge variant="outline" className={statusClass(bundle.status)}>{bundle.status}</Badge>}
        </div>
        <div className="overflow-x-auto">
          <Table>
            <TableHeader>
                <TableRow>
                  <TableHead>Item</TableHead>
                  <TableHead>UOM</TableHead>
                  <TableHead className="text-right">Qty</TableHead>
                  <TableHead className="text-right">Unit price</TableHead>
                  <TableHead className="text-right">Include</TableHead>
                  {editing && isDraft ? <TableHead /> : null}
                </TableRow>
              </TableHeader>
              <TableBody>
                {lines.map((line) => (
                  <TableRow key={line.key}>
                    <TableCell className="min-w-72">
                      <Select value={line.itemId ? String(line.itemId) : "all"} onValueChange={(v) => {
                        const itemId = Number(v)
                        const item = items.find((candidate) => candidate.itemId === itemId)
                        updateLine(line.key, { itemId, unitPrice: item?.salePrice ?? line.unitPrice })
                      }} disabled={!editing || !isDraft}>
                        <SelectTrigger className="h-9 text-sm">
                          <SelectValue placeholder="Select item" />
                        </SelectTrigger>
                        <SelectContent>
                          {items.map((item) => (
                            <SelectItem key={item.itemId} value={String(item.itemId)}>
                              {item.sku} - {item.name}
                            </SelectItem>
                          ))}
                        </SelectContent>
                      </Select>
                    </TableCell>
                    <TableCell className="min-w-40 text-sm text-muted-foreground">
                      {baseUomLabel(items, uoms, line.itemId)}
                    </TableCell>
                    <TableCell className="text-right w-28"><Input type="number" min="0" step="0.01" value={line.qty} onChange={(e) => updateLine(line.key, { qty: Number(e.target.value) })} disabled={!editing || !isDraft} className="text-right" /></TableCell>
                    <TableCell className="text-right w-32"><Input type="number" min="0" step="0.01" value={line.unitPrice} onChange={(e) => updateLine(line.key, { unitPrice: Number(e.target.value) })} disabled={!editing || !isDraft} className="text-right" /></TableCell>
                    <TableCell className="text-right">
                      {editing && isDraft ? (
                        <button
                          type="button"
                          onClick={() => updateLine(line.key, { includeInBundle: !line.includeInBundle })}
                          className={cn(
                            "rounded-full px-3 py-1 text-xs font-medium",
                            line.includeInBundle ? "bg-emerald-50 text-emerald-800" : "bg-muted text-muted-foreground"
                          )}
                        >
                          {line.includeInBundle ? "Included" : "Excluded"}
                        </button>
                      ) : (
                        line.includeInBundle ? "Included" : "Excluded"
                      )}
                    </TableCell>
                    {editing && isDraft ? <TableCell className="text-right"><Button type="button" variant="ghost" size="icon-sm" onClick={() => removeLine(line.key)} disabled={lines.length === 1}><Minus className="size-4" /></Button></TableCell> : null}
                  </TableRow>
                ))}
                {lines.length === 0 ? (
                  <TableRow>
                    <TableCell colSpan={editing && isDraft ? 6 : 5} className="py-10 text-center text-sm text-muted-foreground">
                      No component rows yet. Click Add line to start.
                    </TableCell>
                  </TableRow>
                ) : null}
            </TableBody>
          </Table>
        </div>
      </section>

      <section className="rounded-2xl border bg-card p-4 shadow-sm">
        <div className="grid gap-3 md:grid-cols-3">
          <div><div className="text-xs text-muted-foreground">Component subtotal</div><div className="text-lg font-semibold">{componentSubtotal.toFixed(2)}</div></div>
          <div><div className="text-xs text-muted-foreground">Bundle price</div><div className="text-lg font-semibold">{bundlePrice.toFixed(2)}</div></div>
          <div><div className="text-xs text-muted-foreground">Margin</div><div className="text-lg font-semibold">{(bundlePrice - componentSubtotal).toFixed(2)}</div></div>
        </div>
      </section>
    </div>
  )
}
