"use client"

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

import { itemsApi } from "@/lib/api/items"
import { categoriesApi } from "@/lib/api/categories"
import { uomsApi } from "@/lib/api/uoms"
import { vendorsApi } from "@/lib/api/vendors"
import { warehousesApi } from "@/lib/api/warehouses"
import { errorMessage, fieldErrors } from "@/lib/error-map"
import { validateConversionLine, validateItemForm, validateReorderLine } from "@/lib/validations/master-data"
import { cn } from "@/lib/utils"
import { Item, ItemReorderSetting, ItemType, TrackingMode, UomConversion } from "@/types/master-data"

import { Badge } from "@/components/ui/badge"
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 ReorderDraft {
  key: string
  warehouseId: number | null
  reorderPoint: string
  reorderQty: string
}

interface ConversionDraft {
  key: string
  fromUom: number | null
  toUom: number | null
  factor: string
}

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

export default function ItemDetailPage() {
  const params = useParams<{ id: string }>()
  const router = useRouter()
  const itemId = Number(params.id)

  const [item, setItem] = useState<Item | null>(null)
  const [etag, setEtag] = useState<string | null>(null)
  const [categories, setCategories] = useState<{ categoryId: number; name: string }[]>([])
  const [uoms, setUoms] = useState<{ uomId: number; name: string }[]>([])
  const [vendors, setVendors] = useState<{ vendorId: number; code: string; name: string }[]>([])
  const [warehouses, setWarehouses] = useState<{ warehouseId: number; code: string; name: string }[]>([])
  const [loadError, setLoadError] = useState<string | null>(null)

  // Basic info form
  const [sku, setSku] = useState("")
  const [name, setName] = useState("")
  const [description, setDescription] = useState("")
  const [categoryId, setCategoryId] = useState<number | null>(null)
  const [baseUomId, setBaseUomId] = useState<number | null>(null)
  const [defaultVendorId, setDefaultVendorId] = useState<number | null>(null)
  const [itemType, setItemType] = useState<ItemType>("Stocked")
  const [trackingMode, setTrackingMode] = useState<TrackingMode>("None")
  const [taxClass, setTaxClass] = useState("")

  const [errors, setErrors] = useState<Record<string, string>>({})
  const [conflict, setConflict] = useState(false)
  const [saveError, setSaveError] = useState<string | null>(null)
  const [saving, setSaving] = useState(false)
  const [togglingStatus, setTogglingStatus] = useState(false)

  // Reorder settings
  const [reorderLines, setReorderLines] = useState<ReorderDraft[]>([])
  const [reorderErrors, setReorderErrors] = useState<Record<string, Record<string, string>>>({})
  const [reorderSaveError, setReorderSaveError] = useState<string | null>(null)
  const [savingReorder, setSavingReorder] = useState(false)

  // UOM conversions
  const [conversionLines, setConversionLines] = useState<ConversionDraft[]>([])
  const [conversionErrors, setConversionErrors] = useState<Record<string, Record<string, string>>>({})
  const [conversionSaveError, setConversionSaveError] = useState<string | null>(null)
  const [savingConversions, setSavingConversions] = useState(false)

  function applyItem(data: Item) {
    setItem(data)
    setSku(data.sku)
    setName(data.name)
    setDescription(data.description ?? "")
    setCategoryId(data.categoryId)
    setBaseUomId(data.baseUomId)
    setDefaultVendorId(data.defaultVendorId)
    setItemType(data.itemType)
    setTrackingMode(data.trackingMode)
    setTaxClass(data.taxClass ?? "")
    setReorderLines(data.reorder.map((r): ReorderDraft => ({ key: newKey(), warehouseId: r.warehouseId, reorderPoint: String(r.reorderPoint), reorderQty: String(r.reorderQty) })))
    setConversionLines(data.conversions.map((c): ConversionDraft => ({ key: newKey(), fromUom: c.fromUom, toUom: c.toUom, factor: String(c.factor) })))
  }

  function load() {
    setLoadError(null)
    itemsApi
      .get(itemId)
      .then(({ data, etag: tag }) => {
        applyItem(data)
        setEtag(tag)
        setConflict(false)
      })
      .catch((err) => setLoadError(errorMessage(err)))
  }

  useEffect(() => {
    if (!Number.isFinite(itemId)) return
    load()
    Promise.all([categoriesApi.list(), uomsApi.list(), vendorsApi.list({ pageSize: 200 }), warehousesApi.list()])
      .then(([cat, uo, ve, wh]) => {
        setCategories(cat.items)
        setUoms(uo.items)
        setVendors(ve.items)
        setWarehouses(wh.items)
      })
      .catch(() => {})
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [itemId])

  async function handleSave() {
    if (!item || !etag) return
    setSaveError(null)
    const nextErrors = validateItemForm({ sku, name, categoryId, baseUomId })
    setErrors(nextErrors)
    if (Object.keys(nextErrors).length > 0) return

    setSaving(true)
    try {
      const result = await itemsApi.update(
        item.itemId,
        { sku, name, description: description || null, categoryId: categoryId as number, baseUomId: baseUomId as number, defaultVendorId, itemType, trackingMode, taxClass: taxClass || null },
        etag
      )
      applyItem(result.data)
      setEtag(result.etag)
      toast.success("Item saved", `${result.data.sku} — ${result.data.name}`)
    } catch (err) {
      const code = (err as { code?: string })?.code
      if (code === "CONCURRENCY_CONFLICT") {
        setConflict(true)
        setSaveError(errorMessage(err))
        setSaving(false)
        return
      }
      const fe = fieldErrors(err)
      if (fe?.sku) setErrors((prev) => ({ ...prev, sku: fe.sku }))
      setSaveError(errorMessage(err))
      toast.error("Could not save item", errorMessage(err))
    } finally {
      setSaving(false)
    }
  }

  async function handleToggleStatus() {
    if (!item) return
    const next = item.status === "Active" ? "Inactive" : "Active"
    setTogglingStatus(true)
    try {
      await itemsApi.updateStatus(item.itemId, next)
      toast.success(next === "Active" ? "Item activated" : "Item deactivated")
      load()
    } catch (err) {
      toast.error("Could not update status", errorMessage(err))
    } finally {
      setTogglingStatus(false)
    }
  }

  function updateReorderLine(key: string, patch: Partial<ReorderDraft>) {
    setReorderLines((prev) => prev.map((l) => (l.key === key ? { ...l, ...patch } : l)))
  }
  function removeReorderLine(key: string) {
    setReorderLines((prev) => prev.filter((l) => l.key !== key))
  }

  async function handleSaveReorder() {
    if (!item) return
    setReorderSaveError(null)
    const nextErrors: Record<string, Record<string, string>> = {}
    for (const line of reorderLines) {
      const errs = validateReorderLine({ warehouseId: line.warehouseId, reorderPoint: line.reorderPoint, reorderQty: line.reorderQty })
      if (Object.keys(errs).length > 0) nextErrors[line.key] = errs
    }
    setReorderErrors(nextErrors)
    if (Object.keys(nextErrors).length > 0) {
      setReorderSaveError("Fix the highlighted rows before saving.")
      return
    }

    const settings: ItemReorderSetting[] = reorderLines.map((l) => ({
      warehouseId: l.warehouseId as number,
      reorderPoint: Number(l.reorderPoint),
      reorderQty: Number(l.reorderQty),
    }))

    setSavingReorder(true)
    try {
      const result = await itemsApi.updateReorder(item.itemId, { settings })
      setItem((prev) => (prev ? { ...prev, reorder: result.settings } : prev))
      toast.success("Reorder settings saved")
    } catch (err) {
      setReorderSaveError(errorMessage(err))
      toast.error("Could not save reorder settings", errorMessage(err))
    } finally {
      setSavingReorder(false)
    }
  }

  function updateConversionLine(key: string, patch: Partial<ConversionDraft>) {
    setConversionLines((prev) => prev.map((l) => (l.key === key ? { ...l, ...patch } : l)))
  }
  function removeConversionLine(key: string) {
    setConversionLines((prev) => prev.filter((l) => l.key !== key))
  }

  async function handleSaveConversions() {
    if (!item) return
    setConversionSaveError(null)
    const nextErrors: Record<string, Record<string, string>> = {}
    for (const line of conversionLines) {
      const errs = validateConversionLine({ fromUom: line.fromUom, toUom: line.toUom, factor: line.factor })
      if (Object.keys(errs).length > 0) nextErrors[line.key] = errs
    }
    setConversionErrors(nextErrors)
    if (Object.keys(nextErrors).length > 0) {
      setConversionSaveError("Fix the highlighted rows before saving.")
      return
    }

    const conversions = conversionLines.map((l) => ({ fromUom: l.fromUom as number, toUom: l.toUom as number, factor: Number(l.factor) }))

    setSavingConversions(true)
    try {
      const result = await itemsApi.updateUomConversions(item.itemId, { conversions })
      setItem((prev) => (prev ? { ...prev, conversions: result.conversions } : prev))
      setConversionLines(result.conversions.map((c: UomConversion): ConversionDraft => ({ key: newKey(), fromUom: c.fromUom, toUom: c.toUom, factor: String(c.factor) })))
      toast.success("UOM conversions saved")
    } catch (err) {
      setConversionSaveError(errorMessage(err))
      toast.error("Could not save UOM conversions", errorMessage(err))
    } finally {
      setSavingConversions(false)
    }
  }

  function uomName(uomId: number) {
    return uoms.find((u) => u.uomId === uomId)?.name ?? `#${uomId}`
  }

  if (loadError && !item) {
    return (
      <div className="flex flex-col gap-4">
        <div className="rounded-lg border border-destructive/30 bg-destructive/5 p-5 text-base text-destructive">{loadError}</div>
        <Link href="/dashboard/products" className={cn(buttonVariants({ variant: "outline" }))}>
          Back to items
        </Link>
      </div>
    )
  }

  if (!item) {
    return (
      <div className="flex flex-col gap-3">
        <Skeleton className="h-10 w-72" />
        <Skeleton className="h-48 w-full" />
      </div>
    )
  }

  return (
    <div className="flex flex-col gap-6">
      <div className="flex items-center justify-between">
        <div className="flex items-center gap-3">
          <Link href="/dashboard/products" className={cn(buttonVariants({ variant: "ghost", size: "icon-lg" }))}>
            <ArrowLeft className="size-5" />
          </Link>
          <div>
            <div className="flex items-center gap-3">
              <h1 className="text-2xl font-bold text-foreground">{item.sku}</h1>
              <Badge
                variant="outline"
                className={cn("h-6 w-fit justify-center border-transparent px-2.5 text-sm", item.status === "Active" ? "bg-success/10 text-success" : "bg-muted text-muted-foreground")}
              >
                {item.status}
              </Badge>
            </div>
            <p className="text-base text-muted-foreground">{item.name}</p>
          </div>
        </div>

        <Button size="lg" variant={item.status === "Active" ? "destructive" : "success"} onClick={handleToggleStatus} disabled={togglingStatus}>
          {togglingStatus ? "Updating…" : item.status === "Active" ? "Deactivate" : "Activate"}
        </Button>
      </div>

      {conflict && (
        <div className="flex items-start gap-3 rounded-lg border border-warning/30 bg-warning/5 p-5 text-base text-warning">
          <AlertTriangle className="size-5 shrink-0" />
          <div className="flex flex-col gap-2">
            <p>{saveError ?? "This item was changed by someone else."} Reload before retrying.</p>
            <Button size="sm" variant="outline" onClick={load}>
              Reload
            </Button>
          </div>
        </div>
      )}

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

      <div className="flex flex-col gap-4 rounded-xl border p-5">
        <h2 className="text-base font-semibold text-foreground">Basic info</h2>
        <div className="grid grid-cols-1 gap-4 sm:grid-cols-2">
          <div className="flex flex-col gap-2">
            <Label className="text-base">SKU</Label>
            <Input value={sku} onChange={(e) => setSku(e.target.value)} aria-invalid={!!errors.sku} className="h-12 text-base" disabled={conflict} />
            <FieldError errors={[errors.sku ? { message: errors.sku } : undefined]} />
          </div>
          <div className="flex flex-col gap-2">
            <Label className="text-base">Name</Label>
            <Input value={name} onChange={(e) => setName(e.target.value)} aria-invalid={!!errors.name} className="h-12 text-base" disabled={conflict} />
            <FieldError errors={[errors.name ? { message: errors.name } : undefined]} />
          </div>
          <div className="flex flex-col gap-2 sm:col-span-2">
            <Label className="text-base">Description</Label>
            <Input value={description} onChange={(e) => setDescription(e.target.value)} className="h-12 text-base" disabled={conflict} />
          </div>
          <div className="flex flex-col gap-2">
            <Label className="text-base">Category</Label>
            <Select<number | null> value={categoryId} onValueChange={setCategoryId} disabled={conflict}>
              <SelectTrigger className="h-12! w-full text-base" aria-invalid={!!errors.categoryId}>
                <SelectValue placeholder="Select category" />
              </SelectTrigger>
              <SelectContent>
                {categories.map((c) => (
                  <SelectItem key={c.categoryId} value={c.categoryId} className="text-base">
                    {c.name}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
            <FieldError errors={[errors.categoryId ? { message: errors.categoryId } : undefined]} />
          </div>
          <div className="flex flex-col gap-2">
            <Label className="text-base">Base UOM</Label>
            <Select<number | null> value={baseUomId} onValueChange={setBaseUomId} disabled={conflict}>
              <SelectTrigger className="h-12! w-full text-base" aria-invalid={!!errors.baseUomId}>
                <SelectValue placeholder="Select base UOM" />
              </SelectTrigger>
              <SelectContent>
                {uoms.map((u) => (
                  <SelectItem key={u.uomId} value={u.uomId} className="text-base">
                    {u.name}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
            <FieldError errors={[errors.baseUomId ? { message: errors.baseUomId } : undefined]} />
          </div>
          <div className="flex flex-col gap-2">
            <Label className="text-base">Default vendor</Label>
            <Select<number | null> value={defaultVendorId} onValueChange={setDefaultVendorId} disabled={conflict}>
              <SelectTrigger className="h-12! w-full text-base">
                <SelectValue placeholder="None" />
              </SelectTrigger>
              <SelectContent>
                {vendors.map((v) => (
                  <SelectItem key={v.vendorId} value={v.vendorId} className="text-base">
                    {v.code} — {v.name}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
          </div>
          <div className="flex flex-col gap-2">
            <Label className="text-base">Tax class</Label>
            <Input value={taxClass} onChange={(e) => setTaxClass(e.target.value)} className="h-12 text-base" disabled={conflict} />
          </div>
          <div className="flex flex-col gap-2">
            <Label className="text-base">Item type</Label>
            <Select<ItemType> value={itemType} onValueChange={(v) => v && setItemType(v)} disabled={conflict}>
              <SelectTrigger className="h-12! w-full text-base">
                <SelectValue />
              </SelectTrigger>
              <SelectContent>
                <SelectItem value="Stocked" className="text-base">Stocked</SelectItem>
                <SelectItem value="NonStocked" className="text-base">Non-stocked</SelectItem>
                <SelectItem value="Service" className="text-base">Service</SelectItem>
              </SelectContent>
            </Select>
          </div>
          <div className="flex flex-col gap-2">
            <Label className="text-base">Tracking mode</Label>
            <Select<TrackingMode> value={trackingMode} onValueChange={(v) => v && setTrackingMode(v)} disabled={conflict}>
              <SelectTrigger className="h-12! w-full text-base">
                <SelectValue />
              </SelectTrigger>
              <SelectContent>
                <SelectItem value="None" className="text-base">None</SelectItem>
                <SelectItem value="Batch" className="text-base">Batch</SelectItem>
                <SelectItem value="Serial" className="text-base">Serial</SelectItem>
              </SelectContent>
            </Select>
          </div>
        </div>
        <div className="flex justify-end gap-3">
          <Button variant="outline" size="lg" onClick={() => router.push("/dashboard/products")}>
            Back
          </Button>
          <Button size="lg" onClick={handleSave} disabled={saving || conflict}>
            <Save className="size-5" />
            {saving ? "Saving…" : "Save changes"}
          </Button>
        </div>
      </div>

      <div className="flex flex-col gap-4 rounded-xl border p-5">
        <div className="flex items-center justify-between">
          <div>
            <h2 className="text-base font-semibold text-foreground">Reorder settings</h2>
            <p className="text-sm text-muted-foreground">Per-warehouse reorder point and quantity (FR-MD-05).</p>
          </div>
          <Button type="button" variant="outline" onClick={() => setReorderLines((prev) => [...prev, { key: newKey(), warehouseId: null, reorderPoint: "", reorderQty: "" }])}>
            <Plus className="size-5" />
            Add row
          </Button>
        </div>

        {reorderLines.length > 0 && (
          <Table className="text-base">
            <TableHeader>
              <TableRow>
                <TableHead className="h-12 px-3 text-sm">Warehouse</TableHead>
                <TableHead className="h-12 px-3 text-sm">Reorder point</TableHead>
                <TableHead className="h-12 px-3 text-sm">Reorder qty</TableHead>
                <TableHead className="h-12 w-10 px-3" />
              </TableRow>
            </TableHeader>
            <TableBody>
              {reorderLines.map((line) => {
                const errs = reorderErrors[line.key] ?? {}
                return (
                  <TableRow key={line.key}>
                    <TableCell className="px-3 py-3 align-top">
                      <Select<number | null> value={line.warehouseId} onValueChange={(v) => updateReorderLine(line.key, { warehouseId: v })}>
                        <SelectTrigger className="h-11! w-full text-base" aria-invalid={!!errs.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={[errs.warehouseId ? { message: errs.warehouseId } : undefined]} />
                    </TableCell>
                    <TableCell className="px-3 py-3 align-top">
                      <Input type="number" min="0" step="any" value={line.reorderPoint} aria-invalid={!!errs.reorderPoint} onChange={(e) => updateReorderLine(line.key, { reorderPoint: e.target.value })} className="h-11 text-base" />
                      <FieldError errors={[errs.reorderPoint ? { message: errs.reorderPoint } : undefined]} />
                    </TableCell>
                    <TableCell className="px-3 py-3 align-top">
                      <Input type="number" min="0" step="any" value={line.reorderQty} aria-invalid={!!errs.reorderQty} onChange={(e) => updateReorderLine(line.key, { reorderQty: e.target.value })} className="h-11 text-base" />
                      <FieldError errors={[errs.reorderQty ? { message: errs.reorderQty } : undefined]} />
                    </TableCell>
                    <TableCell className="px-3 py-3 align-top">
                      <Button type="button" variant="ghost" size="icon" onClick={() => removeReorderLine(line.key)} aria-label="Remove row">
                        <Trash2 className="size-5" />
                      </Button>
                    </TableCell>
                  </TableRow>
                )
              })}
            </TableBody>
          </Table>
        )}

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

        <div className="flex justify-end">
          <Button type="button" onClick={handleSaveReorder} disabled={savingReorder}>
            {savingReorder ? "Saving…" : "Save reorder settings"}
          </Button>
        </div>
      </div>

      <div className="flex flex-col gap-4 rounded-xl border p-5">
        <div className="flex items-center justify-between">
          <div>
            <h2 className="text-base font-semibold text-foreground">UOM conversions</h2>
            <p className="text-sm text-muted-foreground">Purchase/stock UOM → base UOM conversion factors (FR-MD-02/03).</p>
          </div>
          <Button type="button" variant="outline" onClick={() => setConversionLines((prev) => [...prev, { key: newKey(), fromUom: null, toUom: item.baseUomId, factor: "" }])}>
            <Plus className="size-5" />
            Add row
          </Button>
        </div>

        {conversionLines.length > 0 && (
          <Table className="text-base">
            <TableHeader>
              <TableRow>
                <TableHead className="h-12 px-3 text-sm">From UOM</TableHead>
                <TableHead className="h-12 px-3 text-sm">To UOM</TableHead>
                <TableHead className="h-12 px-3 text-sm">Factor</TableHead>
                <TableHead className="h-12 w-10 px-3" />
              </TableRow>
            </TableHeader>
            <TableBody>
              {conversionLines.map((line) => {
                const errs = conversionErrors[line.key] ?? {}
                return (
                  <TableRow key={line.key}>
                    <TableCell className="px-3 py-3 align-top">
                      <Select<number | null> value={line.fromUom} onValueChange={(v) => updateConversionLine(line.key, { fromUom: v })}>
                        <SelectTrigger className="h-11! w-full text-base" aria-invalid={!!errs.fromUom}>
                          <SelectValue placeholder="From" />
                        </SelectTrigger>
                        <SelectContent>
                          {uoms.map((u) => (
                            <SelectItem key={u.uomId} value={u.uomId} className="text-base">
                              {u.name}
                            </SelectItem>
                          ))}
                        </SelectContent>
                      </Select>
                      <FieldError errors={[errs.fromUom ? { message: errs.fromUom } : undefined]} />
                    </TableCell>
                    <TableCell className="px-3 py-3 align-top">
                      <Select<number | null> value={line.toUom} onValueChange={(v) => updateConversionLine(line.key, { toUom: v })}>
                        <SelectTrigger className="h-11! w-full text-base" aria-invalid={!!errs.toUom}>
                          <SelectValue placeholder="To" />
                        </SelectTrigger>
                        <SelectContent>
                          {uoms.map((u) => (
                            <SelectItem key={u.uomId} value={u.uomId} className="text-base">
                              {u.name}
                            </SelectItem>
                          ))}
                        </SelectContent>
                      </Select>
                      <FieldError errors={[errs.toUom ? { message: errs.toUom } : undefined]} />
                    </TableCell>
                    <TableCell className="px-3 py-3 align-top">
                      <Input type="number" min="0" step="any" value={line.factor} aria-invalid={!!errs.factor} onChange={(e) => updateConversionLine(line.key, { factor: e.target.value })} className="h-11 text-base" />
                      <FieldError errors={[errs.factor ? { message: errs.factor } : undefined]} />
                    </TableCell>
                    <TableCell className="px-3 py-3 align-top">
                      <Button type="button" variant="ghost" size="icon" onClick={() => removeConversionLine(line.key)} aria-label="Remove row">
                        <Trash2 className="size-5" />
                      </Button>
                    </TableCell>
                  </TableRow>
                )
              })}
            </TableBody>
          </Table>
        )}

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

        <div className="flex justify-end">
          <Button type="button" onClick={handleSaveConversions} disabled={savingConversions}>
            {savingConversions ? "Saving…" : "Save conversions"}
          </Button>
        </div>
      </div>

      <p className="text-sm text-muted-foreground">
        {uomName(item.baseUomId)} is the base UOM — every transaction converts to and stores quantities in base UOM (FR-MD-03). {warehouses.length === 0 && "No warehouses configured yet."}
      </p>
    </div>
  )
}
