"use client"

import { Suspense, useEffect, useMemo, useState } from "react"
import { useRouter, useSearchParams } from "next/navigation"
import Link from "next/link"
import { ArrowLeft, ExternalLink, Minus, Plus, Save } from "lucide-react"

import { bundleApi } from "@/lib/api/bundles"
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 { errorMessage } from "@/lib/error-map"
import { Button, buttonVariants } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"
import { Skeleton } from "@/components/ui/skeleton"
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"
import { cn } from "@/lib/utils"
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 { BundleSaleTemplate, BundleSaleTemplateLine, BundleSaleTemplateSummary, CreateBundleSaleRequest } from "@/types/bundles"

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 NewBundleSaleContent() {
  const router = useRouter()
  const searchParams = useSearchParams()
  const templateFromQuery = searchParams.get("templateId")
  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 [templates, setTemplates] = useState<BundleSaleTemplateSummary[]>([])
  const [template, setTemplate] = useState<BundleSaleTemplate | null>(null)
  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>(templateFromQuery ? Number(templateFromQuery) : null)
  const [bundleName, setBundleName] = useState("Demo Bundle")
  const [bundlePrice, setBundlePrice] = useState<number>(0)
  const [allowPriceOverride, setAllowPriceOverride] = useState(false)
  const [lines, setLines] = useState<EditableLine[]>([])
  const [loading, setLoading] = useState(true)
  const [saving, setSaving] = useState(false)
  const [submitError, setSubmitError] = useState<string | null>(null)

  useEffect(() => {
    Promise.all([
      customersApi.list({ pageSize: 200 }),
      itemsApi.list({ pageSize: 200 }),
      uomsApi.list({ pageSize: 200 }),
      warehousesApi.list({ pageSize: 200 }),
      usersApi.list({ pageSize: 200 }),
      bundleApi.listTemplates({ pageSize: 200 }),
    ])
      .then(([cust, itemRes, uomRes, whRes, userRes, templateRes]) => {
        setCustomers(cust.items)
        setItems(itemRes.items)
        setUoms(uomRes.items)
        setWarehouses(whRes.items)
        setUsers(userRes.items)
        setTemplates(templateRes.items)
        setCustomerId(cust.items[0]?.customerId ?? null)
        setWarehouseId(whRes.items[0]?.warehouseId ?? null)
        setCashierUserId(userRes.items[0]?.userId ?? null)
        setTemplateId((current) => current ?? templateRes.items[0]?.bundleSaleTemplateId ?? null)
      })
      .catch((err) => setSubmitError(errorMessage(err)))
      .finally(() => setLoading(false))
  }, [])

  useEffect(() => {
    if (!templateId) return
    bundleApi.getTemplate(templateId).then((res) => {
      setTemplate(res)
      setLines(
        res.lines.length > 0
          ? res.lines.map((line) => {
              const item = items.find((candidate) => candidate.itemId === line.itemId)
              return createBlankLine({
                ...line,
              })
            })
          : [createBlankLine()]
      )
      setBundlePrice(res.lines.reduce((sum, line) => sum + line.qty * line.unitPrice, 0))
    }).catch((err) => setSubmitError(errorMessage(err)))
  }, [items, templateId])

  const templateLabel = useMemo(() => template?.templateName ?? "Select template", [template])
  const componentSubtotal = useMemo(() => lines.reduce((sum, line) => sum + Number(line.qty || 0) * Number(line.unitPrice || 0), 0), [lines])

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

  function addLine() {
    setLines((prev) => [...prev, createBlankLine(template?.lines[0])])
  }

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

  async function submit() {
    if (!customerId || !warehouseId || !cashierUserId || !templateId || !template) {
      setSubmitError("Select customer, warehouse, cashier, and bundle template.")
      return
    }
    if (lines.length === 0) {
      setSubmitError("Add at least one bundle component line.")
      return
    }
    setSaving(true)
    setSubmitError(null)
    try {
      const request: CreateBundleSaleRequest = {
        customerId,
        warehouseId,
        cashierUserId,
        bundleSaleTemplateId: templateId,
        bundleName,
        bundlePrice,
        allowPriceOverride,
        lines: lines.map(({ key, ...line }) => line),
      }
      const res = await bundleApi.createBundle(request)
      toast.success("Bundle saved", res.bundleNo)
      router.push(`/dashboard/sales/bundles/${res.bundleSaleId}`)
    } catch (err) {
      setSubmitError(errorMessage(err))
    } finally {
      setSaving(false)
    }
  }

  if (loading) return <div className="rounded-2xl border border-dashed p-8 text-muted-foreground">Loading masters...</div>

  return (
    <div className="flex flex-col gap-6">
      <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">Create bundle sale</h1>
          <p className="text-base text-muted-foreground">Create a fixed bundle from a stored template.</p>
        </div>
      </div>

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

      <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">Need stock before saving this bundle?</div>
            <div className="mt-1">Save the bundle as a draft first. After that, open the draft detail page to check shortages and create a GRN if needed.</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>

      <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))}>
              <SelectTrigger><SelectValue placeholder="Select 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))}>
              <SelectTrigger><SelectValue placeholder="Select 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))}>
              <SelectTrigger><SelectValue placeholder="Select 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))}>
              <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)} />
          </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))} />
          </div>
          <div className="space-y-1.5">
            <Label>Override allowed</Label>
            <button type="button" onClick={() => setAllowPriceOverride((v) => !v)} className={cn("flex h-10 w-full items-center justify-center rounded-md border px-3 text-sm font-medium", allowPriceOverride ? "border-emerald-200 bg-emerald-50 text-emerald-800" : "border-border text-muted-foreground")}>
              {allowPriceOverride ? "Yes" : "No"}
            </button>
          </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">Editable component rows</h2>
            <p className="text-xs text-muted-foreground">These rows are sent to the backend and stored with the bundle.</p>
          </div>
          <Button type="button" variant="outline" size="sm" onClick={addLine}><Plus className="size-4" /> Add component</Button>
        </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>
                <TableHead />
              </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,
                        })
                    }}>
                      <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) })} 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) })} className="text-right" /></TableCell>
                  <TableCell className="text-right">
                    <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>
                  </TableCell>
                  <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>
                </TableRow>
              ))}
              {lines.length === 0 && (
                <TableRow>
                  <TableCell colSpan={6} className="py-10 text-center text-sm text-muted-foreground">
                    No component rows yet. Click Add component to start.
                  </TableCell>
                </TableRow>
              )}
            </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 className="flex justify-end gap-3">
        <Link href="/dashboard/sales/bundles" className={cn(buttonVariants({ variant: "outline", size: "lg" }))}>Cancel</Link>
        <Button size="lg" onClick={submit} disabled={saving}>
          <Save className="size-4" />
          {saving ? "Saving..." : "Save draft"}
        </Button>
      </div>
    </div>
  )
}

export default function NewBundleSalePage() {
  return (
    <Suspense fallback={<Skeleton className="h-48 w-full" />}>
      <NewBundleSaleContent />
    </Suspense>
  )
}
