"use client"

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

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 { Badge } from "@/components/ui/badge"
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"
import { cn } from "@/lib/utils"
import { getSuggestedUnitPrice } from "@/lib/sales-line-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 { Customer } from "@/types/customers"
import { ItemListItem, Uom, Warehouse } from "@/types/master-data"
import { ManagedUser } from "@/types/users"
import { CreateSalesSlipLineRequest, CreateSalesSlipRequest } from "@/types/sales"
import { toast } from "@/components/ui/toast"

type Line = CreateSalesSlipLineRequest & { key: string }

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,
})

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

export default function NewSalesSlipPage() {
  const router = useRouter()
  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 [loading, setLoading] = useState(true)
  const [submitError, setSubmitError] = useState<string | null>(null)
  const [saving, setSaving] = useState(false)

  useEffect(() => {
    Promise.all([
      customersApi.list({ pageSize: 200 }),
      itemsApi.list({ pageSize: 200 }),
      uomsApi.list({ pageSize: 200 }),
      warehousesApi.list({ pageSize: 200 }),
      usersApi.list({ pageSize: 200 }),
    ])
      .then(([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,
            unitPrice: getSuggestedUnitPrice(itemRes.items, itemRes.items[0]?.itemId),
          },
        ])
      })
      .catch((err) => setSubmitError(errorMessage(err)))
      .finally(() => setLoading(false))
  }, [])

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

  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()}`)])
  }

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

  const grossTotal = useMemo(
    () => lines.reduce((sum, line) => sum + Number(line.unitPrice ?? 0) * Number(line.qty || 0), 0),
    [lines],
  )
  const discountTotal = useMemo(
    () =>
      lines.reduce((sum, line) => {
        const gross = Number(line.unitPrice ?? 0) * Number(line.qty || 0)
        const mode = String(line.discountMode)
        return sum + (mode === "Amount" ? Number(line.discountAmount || 0) : gross * (Number(line.discountPct || 0) / 100))
      }, 0),
    [lines],
  )
  const taxTotal = useMemo(
    () =>
      lines.reduce((sum, line) => {
        const gross = Number(line.unitPrice ?? 0) * Number(line.qty || 0)
        const mode = String(line.discountMode)
        const discount = mode === "Amount" ? Number(line.discountAmount || 0) : gross * (Number(line.discountPct || 0) / 100)
        const taxable = Math.max(0, gross - discount)
        return sum + taxable * (Number(line.taxPct || 0) / 100)
      }, 0),
    [lines],
  )
  const netTotal = Math.max(0, grossTotal - discountTotal)
  const payableTotal = netTotal + taxTotal

  async function submit() {
    if (!customerId || !warehouseId || !cashierUserId) return setSubmitError("Select customer, warehouse, and cashier.")
    if (lines.some((line) => Number(line.itemId) === 0)) return setSubmitError("Select an item for every line.")
    if (lines.some((line) => Number(line.warehouseId) === 0)) return setSubmitError("Select a warehouse for every line.")

    const payload: CreateSalesSlipRequest = {
      customerId,
      warehouseId,
      cashierUserId,
      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,
      })),
    }

    setSaving(true)
    setSubmitError(null)
    try {
      const created = await salesApi.createSlip(payload)
      toast.success("Slip created", created.data.slipNo)
      router.push(`/dashboard/sales/slips/${created.data.salesSlipId}`)
    } catch (err) {
      setSubmitError(errorMessage(err))
    } finally {
      setSaving(false)
    }
  }

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

  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/slips" className={cn(buttonVariants({ variant: "outline", size: "icon" }))}>
            <ArrowLeft className="size-4" />
          </Link>
          <div>
            <h1 className="text-2xl font-bold text-foreground">New sales slip</h1>
            <p className="text-base text-muted-foreground">Create counter sales slips from the live backend.</p>
          </div>
        </div>
        <div className="flex flex-wrap gap-2">
          <Button type="button" variant="outline" size="sm" onClick={addLine}>
            <Plus className="size-4" /> Add line
          </Button>
          <Button size="sm" onClick={submit} disabled={saving}>
            <Save className="size-4" /> {saving ? "Saving..." : "Save slip"}
          </Button>
        </div>
      </div>

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

      <section className="rounded-2xl border border-border bg-card p-4 shadow-[var(--shadow-panel)]">
        <h2 className="text-sm font-semibold">Slip header</h2>
        <div className="mt-3 grid gap-4 sm:grid-cols-2 lg:grid-cols-4">
          <div className="space-y-1.5">
            <Label className="text-xs">Customer</Label>
            <Select value={customerId ? String(customerId) : ""} onValueChange={(v) => setCustomerId(v ? Number(v) : null)}>
              <SelectTrigger className="h-9 text-sm">
                <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 className="text-xs">Warehouse</Label>
            <Select value={warehouseId ? String(warehouseId) : ""} onValueChange={(v) => setWarehouseId(v ? Number(v) : null)}>
              <SelectTrigger className="h-9 text-sm">
                <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 className="text-xs">Cashier</Label>
            <Select value={cashierUserId ? String(cashierUserId) : ""} onValueChange={(v) => setCashierUserId(v ? Number(v) : null)}>
              <SelectTrigger className="h-9 text-sm">
                <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 className="text-xs">Slip summary</Label>
            <div className="flex h-9 items-center gap-2 rounded-md border border-border bg-secondary/40 px-3 text-xs text-muted-foreground">
              <Badge variant="outline" className="border-emerald-200 bg-emerald-50 text-emerald-800">
                Draft
              </Badge>
              <span>{lkr.format(payableTotal)}</span>
            </div>
          </div>
        </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">Slip lines</h2>
          <Button type="button" variant="outline" size="sm" onClick={addLine}>
            <Plus className="size-4" /> Add line
          </Button>
        </div>
        <div className="overflow-x-auto">
          <Table className="text-sm">
            <TableHeader>
              <TableRow>
                <TableHead className="h-12 px-4 text-sm">#</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 text-right">Unit price</TableHead>
                <TableHead className="h-12 px-4 text-sm text-right">Discount %</TableHead>
                <TableHead className="h-12 px-4 text-sm text-right">Line total</TableHead>
                <TableHead className="h-12 px-4 text-sm" />
              </TableRow>
            </TableHeader>
            <TableBody>
              {lines.map((line, idx) => {
                const lineGross = Number(line.unitPrice ?? 0) * Number(line.qty || 0)
                const lineDiscount =
                  String(line.discountMode) === "Amount"
                    ? Number(line.discountAmount || 0)
                    : lineGross * (Number(line.discountPct || 0) / 100)
                const lineNet = Math.max(0, lineGross - lineDiscount)

                return (
                  <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-64">
                      <Select value={line.itemId ? String(line.itemId) : ""} onValueChange={(v) => selectItem(line.key, Number(v))}>
                        <SelectTrigger className="h-9 text-sm">
                          <SelectValue placeholder="Select item" />
                        </SelectTrigger>
                        <SelectContent>
                          {items.map((candidate) => (
                            <SelectItem key={candidate.itemId} value={String(candidate.itemId)}>
                              {candidate.sku} - {candidate.name}
                            </SelectItem>
                          ))}
                        </SelectContent>
                      </Select>
                    </TableCell>
                    <TableCell className="px-4 py-2 min-w-36 text-sm text-muted-foreground">
                      {baseUomLabel(items, uoms, line.itemId)}
                    </TableCell>
                    <TableCell className="px-4 py-2">
                      <Input
                        type="number"
                        min="0"
                        step="0.01"
                        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="0.01"
                        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">
                      <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-9 w-28 text-right font-mono text-sm tabular-nums"
                      />
                      <div className="mt-1 text-[11px] text-muted-foreground">
                        {getSuggestedUnitPrice(items, line.itemId) !== null
                          ? `Suggested: ${lkr.format(getSuggestedUnitPrice(items, line.itemId) ?? 0)}`
                          : "No price suggestion available"}
                      </div>
                    </TableCell>
                    <TableCell className="px-4 py-2">
                      <Input
                        type="number"
                        min="0"
                        max="100"
                        step="0.5"
                        value={line.discountPct}
                        onChange={(e) => updateLine(line.key, { discountPct: Number(e.target.value) || 0 })}
                        className="h-9 w-24 text-right font-mono text-sm tabular-nums"
                      />
                    </TableCell>
                    <TableCell className="px-4 py-2 text-right font-mono font-semibold tabular-nums">{lkr.format(lineNet)}</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="grid gap-4 md:grid-cols-2">
        <div className="rounded-2xl border border-border bg-card p-4 shadow-[var(--shadow-panel)]">
          <h3 className="text-sm font-semibold">Slip notes</h3>
          <ul className="mt-3 space-y-2 text-sm text-muted-foreground">
            <li className="rounded-md border border-border px-3 py-2">Cashier posting follows the standard sales-slip workflow.</li>
            <li className="rounded-md border border-border px-3 py-2">Free issue lines are captured from the slip itself, not from a separate register here.</li>
            <li className="rounded-md border border-border px-3 py-2">Use the slip detail page after save to post or cancel.</li>
          </ul>
        </div>

        <dl className="rounded-2xl border border-border bg-card p-4 text-sm shadow-[var(--shadow-panel)]">
          {[
            ["Gross", lkr.format(grossTotal)],
            ["Discount", `-${lkr.format(discountTotal)}`],
            ["Net", lkr.format(netTotal)],
            ["Tax", lkr.format(taxTotal)],
          ].map(([k, v]) => (
            <div key={k} className="flex items-center justify-between py-1.5">
              <dt className="text-muted-foreground">{k}</dt>
              <dd className="font-mono tabular-nums">{v}</dd>
            </div>
          ))}
          <div className="mt-2 flex items-center justify-between border-t border-border pt-3">
            <dt className="font-semibold">Payable</dt>
            <dd className="font-mono text-base font-semibold tabular-nums">{lkr.format(payableTotal)}</dd>
          </div>
        </dl>
      </section>

      <div className="flex justify-end gap-3">
        <Link href="/dashboard/sales/slips" className={cn(buttonVariants({ variant: "outline", size: "lg" }))}>
          Cancel
        </Link>
        <Button size="lg" onClick={submit} disabled={saving}>
          {saving ? "Saving..." : "Create slip"}
        </Button>
      </div>
    </div>
  )
}
