"use client"

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

import { purchaseOrdersApi } from "@/lib/api/purchase-orders"
import { requisitionsApi } from "@/lib/api/requisitions"
import { rfqsApi } from "@/lib/api/rfqs"
import { vendorsApi } from "@/lib/api/vendors"
import { warehousesApi } from "@/lib/api/warehouses"
import { itemsApi } from "@/lib/api/items"
import { uomsApi } from "@/lib/api/uoms"
import { errorMessage } from "@/lib/error-map"
import { validatePoLine } from "@/lib/validations/procurement"
import { cn } from "@/lib/utils"
import { CreatePoLineInput } from "@/types/procurement"
import { ItemListItem, Uom, Vendor, Warehouse } from "@/types/master-data"

import { Button, buttonVariants } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"
import { FieldError } from "@/components/ui/field"
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"
import { Skeleton } from "@/components/ui/skeleton"
import { toast } from "@/components/ui/toast"

interface DraftLine {
  key: string
  itemId: number | null
  uomId: number | null
  warehouseId: number | null
  qty: string
  unitPrice: string
  tax: string
}

let keySeq = 0
function newKey() {
  keySeq += 1
  return `poline-${keySeq}`
}

function emptyLine(): DraftLine {
  return { key: newKey(), itemId: null, uomId: null, warehouseId: null, qty: "", unitPrice: "", tax: "0.18" }
}

function NewPurchaseOrderContent() {
  const router = useRouter()
  const searchParams = useSearchParams()
  const requisitionId = Number(searchParams.get("requisitionId")) || null
  const rfqId = Number(searchParams.get("rfqId")) || null
  const rfqVendorId = Number(searchParams.get("vendorId")) || null

  const [items, setItems] = useState<ItemListItem[] | null>(null)
  const [uoms, setUoms] = useState<Uom[] | null>(null)
  const [warehouses, setWarehouses] = useState<Warehouse[] | null>(null)
  const [vendors, setVendors] = useState<Vendor[] | null>(null)
  const [prefillLoading, setPrefillLoading] = useState(!!requisitionId || !!rfqId)
  const [loadError, setLoadError] = useState<string | null>(null)

  const [vendorId, setVendorId] = useState<number | null>(rfqVendorId)
  const [lines, setLines] = useState<DraftLine[]>([emptyLine()])

  const [headerError, setHeaderError] = useState<string | null>(null)
  const [lineErrors, setLineErrors] = useState<Record<string, Record<string, string>>>({})
  const [submitError, setSubmitError] = useState<string | null>(null)
  const [submitting, setSubmitting] = useState(false)

  useEffect(() => {
    Promise.all([
      itemsApi.list({ pageSize: 200, status: "Active" }),
      uomsApi.list(),
      warehousesApi.list(),
      vendorsApi.list({ pageSize: 200, status: "Active" }),
    ])
      .then(([it, uo, wh, ve]) => {
        setItems(it.items)
        setUoms(uo.items)
        setWarehouses(wh.items)
        setVendors(ve.items)
      })
      .catch((err) => setLoadError(errorMessage(err)))
  }, [])

  useEffect(() => {
    if (requisitionId) {
      requisitionsApi
        .get(requisitionId)
        .then((req) => {
          setLines(
            req.lines.map(
              (l): DraftLine => ({
                key: newKey(),
                itemId: l.itemId,
                uomId: null,
                warehouseId: null,
                qty: String(l.qty),
                unitPrice: "",
                tax: "0.18",
              })
            )
          )
        })
        .catch((err) => setHeaderError(errorMessage(err)))
        .finally(() => setPrefillLoading(false))
      return
    }

    if (rfqId && rfqVendorId) {
      Promise.all([rfqsApi.get(rfqId), rfqsApi.comparison(rfqId)])
        .then(([rfq, comparison]) => {
          setVendorId(rfqVendorId)
          setLines(
            rfq.lines.map((l): DraftLine => {
              const cell = comparison.lines.find((cl) => cl.itemId === l.itemId)?.cells.find((c) => c.vendorId === rfqVendorId)
              return {
                key: newKey(),
                itemId: l.itemId,
                uomId: null,
                warehouseId: null,
                qty: String(l.qty),
                unitPrice: cell ? String(cell.unitPrice) : "",
                tax: "0.18",
              }
            })
          )
        })
        .catch((err) => setHeaderError(errorMessage(err)))
        .finally(() => setPrefillLoading(false))
      return
    }

    setPrefillLoading(false)
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [requisitionId, rfqId, rfqVendorId])

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

  function removeLine(key: string) {
    setLines((prev) => prev.filter((l) => l.key !== key))
  }

  function itemFor(itemId: number | null) {
    return items?.find((i) => i.itemId === itemId) ?? null
  }

  async function handleSubmit() {
    setHeaderError(null)
    setSubmitError(null)

    if (!vendorId) {
      setHeaderError("Select a vendor.")
      return
    }
    if (lines.length === 0) {
      setSubmitError("Add at least one line.")
      return
    }

    const nextLineErrors: Record<string, Record<string, string>> = {}
    for (const line of lines) {
      const errors = validatePoLine({
        itemId: line.itemId,
        uomId: line.uomId,
        warehouseId: line.warehouseId,
        qty: line.qty,
        unitPrice: line.unitPrice,
        tax: line.tax,
      })
      if (Object.keys(errors).length > 0) nextLineErrors[line.key] = errors
    }
    setLineErrors(nextLineErrors)
    if (Object.keys(nextLineErrors).length > 0) {
      setSubmitError("Fix the highlighted lines before submitting.")
      return
    }

    const payloadLines: CreatePoLineInput[] = lines.map((l) => ({
      itemId: l.itemId as number,
      uomId: l.uomId as number,
      warehouseId: l.warehouseId as number,
      qty: Number(l.qty),
      unitPrice: Number(l.unitPrice),
      tax: Number(l.tax),
    }))

    setSubmitting(true)
    try {
      const { data: po } = await purchaseOrdersApi.create({
        vendorId,
        requisitionId: requisitionId ?? (rfqId ? undefined : null),
        lines: payloadLines,
      })
      toast.success("Purchase order created", `${po.docNo} — auto-approved (FR-PROC-04).`)
      router.push(`/dashboard/procurement/purchase-orders/${po.poId}`)
    } catch (err) {
      setSubmitError(errorMessage(err))
      toast.error("Could not create purchase order", errorMessage(err))
    } finally {
      setSubmitting(false)
    }
  }

  const loading = !items || !uoms || !warehouses || !vendors || prefillLoading

  return (
    <div className="flex flex-col gap-6">
      <div className="flex items-center gap-3">
        <Link href="/dashboard/procurement/purchase-orders" className={cn(buttonVariants({ variant: "ghost", size: "icon-lg" }))}>
          <ArrowLeft className="size-5" />
        </Link>
        <div>
          <h1 className="text-2xl font-bold text-foreground">New Purchase Order</h1>
          <p className="text-base text-muted-foreground">Auto-approved on creation; freely editable while open (FR-PROC-03..05).</p>
        </div>
      </div>

      {loadError && (
        <div className="rounded-lg border border-destructive/30 bg-destructive/5 p-5 text-base text-destructive">{loadError}</div>
      )}

      {loading && !loadError && <Skeleton className="h-24 w-full" />}

      {!loading && (
        <>
          <div className="grid grid-cols-1 gap-4 sm:grid-cols-3">
            <div className="flex flex-col gap-2">
              <Label className="text-base">Vendor</Label>
              <Select<number | null> value={vendorId} onValueChange={setVendorId}>
                <SelectTrigger className="h-12! w-full text-base">
                  <SelectValue placeholder="Select vendor" />
                </SelectTrigger>
                <SelectContent>
                  {(vendors ?? []).map((v) => (
                    <SelectItem key={v.vendorId} value={v.vendorId} className="text-base">
                      {v.code} — {v.name}
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </div>
            {requisitionId && (
              <div className="flex flex-col justify-end pb-2.5 text-sm text-muted-foreground">From Requisition #{requisitionId}</div>
            )}
            {rfqId && <div className="flex flex-col justify-end pb-2.5 text-sm text-muted-foreground">From RFQ #{rfqId}</div>}
          </div>

          {headerError && (
            <div className="rounded-lg border border-destructive/30 bg-destructive/5 p-4 text-base text-destructive">{headerError}</div>
          )}

          <div className="flex flex-col gap-3">
            <div className="flex items-center justify-between">
              <h2 className="text-base font-semibold text-foreground">Lines</h2>
              <Button type="button" variant="outline" onClick={() => setLines((prev) => [...prev, emptyLine()])}>
                <Plus className="size-5" />
                Add line
              </Button>
            </div>

            {lines.length > 0 && (
              <div className="overflow-x-auto">
                <Table className="text-base">
                  <TableHeader>
                    <TableRow>
                      <TableHead className="h-12 w-56 px-3 text-sm">Item</TableHead>
                      <TableHead className="h-12 w-28 px-3 text-sm">UOM</TableHead>
                      <TableHead className="h-12 w-40 px-3 text-sm">Warehouse</TableHead>
                      <TableHead className="h-12 w-24 px-3 text-sm">Qty</TableHead>
                      <TableHead className="h-12 w-28 px-3 text-sm">Unit price</TableHead>
                      <TableHead className="h-12 w-24 px-3 text-sm">Tax</TableHead>
                      <TableHead className="h-12 w-10 px-3" />
                    </TableRow>
                  </TableHeader>
                  <TableBody>
                    {lines.map((line) => {
                      const errors = lineErrors[line.key] ?? {}
                      const item = itemFor(line.itemId)
                      return (
                        <TableRow key={line.key}>
                          <TableCell className="px-3 py-3 align-top">
                            {requisitionId || rfqId ? (
                              <div className="flex h-11 items-center text-base">{item ? `${item.sku} — ${item.name}` : `Item #${line.itemId}`}</div>
                            ) : (
                              <>
                                <Select<number | null> value={line.itemId} onValueChange={(v) => updateLine(line.key, { itemId: v })}>
                                  <SelectTrigger className="h-11! w-full text-base" aria-invalid={!!errors.itemId}>
                                    <SelectValue placeholder="Select item" />
                                  </SelectTrigger>
                                  <SelectContent>
                                    {(items ?? []).map((i) => (
                                      <SelectItem key={i.itemId} value={i.itemId} className="text-base">
                                        {i.sku} — {i.name}
                                      </SelectItem>
                                    ))}
                                  </SelectContent>
                                </Select>
                                <FieldError errors={[errors.itemId ? { message: errors.itemId } : undefined]} />
                              </>
                            )}
                          </TableCell>
                          <TableCell className="px-3 py-3 align-top">
                            <Select<number | null> value={line.uomId} onValueChange={(v) => updateLine(line.key, { uomId: v })}>
                              <SelectTrigger className="h-11! w-full text-base" aria-invalid={!!errors.uomId}>
                                <SelectValue placeholder="UOM" />
                              </SelectTrigger>
                              <SelectContent>
                                {(uoms ?? []).map((u) => (
                                  <SelectItem key={u.uomId} value={u.uomId} className="text-base">
                                    {u.name}
                                  </SelectItem>
                                ))}
                              </SelectContent>
                            </Select>
                            <FieldError errors={[errors.uomId ? { message: errors.uomId } : undefined]} />
                          </TableCell>
                          <TableCell className="px-3 py-3 align-top">
                            <Select<number | null> value={line.warehouseId} onValueChange={(v) => updateLine(line.key, { warehouseId: v })}>
                              <SelectTrigger className="h-11! w-full text-base" aria-invalid={!!errors.warehouseId}>
                                <SelectValue placeholder="Warehouse" />
                              </SelectTrigger>
                              <SelectContent>
                                {(warehouses ?? []).map((w) => (
                                  <SelectItem key={w.warehouseId} value={w.warehouseId} className="text-base">
                                    {w.code}
                                  </SelectItem>
                                ))}
                              </SelectContent>
                            </Select>
                            <FieldError errors={[errors.warehouseId ? { message: errors.warehouseId } : undefined]} />
                          </TableCell>
                          <TableCell className="px-3 py-3 align-top">
                            <Input
                              type="number"
                              min="0"
                              step="any"
                              value={line.qty}
                              aria-invalid={!!errors.qty}
                              onChange={(e) => updateLine(line.key, { qty: e.target.value })}
                              className="h-11 text-base"
                            />
                            <FieldError errors={[errors.qty ? { message: errors.qty } : undefined]} />
                          </TableCell>
                          <TableCell className="px-3 py-3 align-top">
                            <Input
                              type="number"
                              min="0"
                              step="any"
                              value={line.unitPrice}
                              aria-invalid={!!errors.unitPrice}
                              onChange={(e) => updateLine(line.key, { unitPrice: e.target.value })}
                              className="h-11 text-base"
                            />
                            <FieldError errors={[errors.unitPrice ? { message: errors.unitPrice } : undefined]} />
                          </TableCell>
                          <TableCell className="px-3 py-3 align-top">
                            <Input
                              type="number"
                              min="0"
                              step="0.01"
                              value={line.tax}
                              aria-invalid={!!errors.tax}
                              onChange={(e) => updateLine(line.key, { tax: e.target.value })}
                              className="h-11 text-base"
                            />
                            <FieldError errors={[errors.tax ? { message: errors.tax } : undefined]} />
                          </TableCell>
                          <TableCell className="px-3 py-3 align-top">
                            <Button type="button" variant="ghost" size="icon" onClick={() => removeLine(line.key)} aria-label="Remove line">
                              <Trash2 className="size-5" />
                            </Button>
                          </TableCell>
                        </TableRow>
                      )
                    })}
                  </TableBody>
                </Table>
              </div>
            )}
          </div>

          {submitError && (
            <div className="rounded-lg border border-destructive/30 bg-destructive/5 p-4 text-base text-destructive">{submitError}</div>
          )}

          <div className="flex justify-end gap-3">
            <Link href="/dashboard/procurement/purchase-orders" className={cn(buttonVariants({ variant: "outline", size: "lg" }))}>
              Cancel
            </Link>
            <Button size="lg" type="button" onClick={handleSubmit} disabled={submitting}>
              {submitting ? "Creating…" : "Create PO"}
            </Button>
          </div>
        </>
      )}
    </div>
  )
}

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