"use client"

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

import { stockTransfersApi } from "@/lib/api/stock-transfers"
import { warehousesApi } from "@/lib/api/warehouses"
import { itemsApi } from "@/lib/api/items"
import { errorMessage } from "@/lib/error-map"
import { cn } from "@/lib/utils"
import { CreateTransferLineInput } from "@/types/stock"
import { Bin, ItemListItem, 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
  destBinId: number | null
  qty: string
}

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

function emptyLine(): DraftLine {
  return { key: newKey(), itemId: null, destBinId: null, qty: "" }
}

export default function NewTransferPage() {
  const router = useRouter()

  const [warehouses, setWarehouses] = useState<Warehouse[] | null>(null)
  const [items, setItems] = useState<ItemListItem[] | null>(null)
  const [srcBins, setSrcBins] = useState<Bin[]>([])
  const [destBins, setDestBins] = useState<Bin[]>([])
  const [loadError, setLoadError] = useState<string | null>(null)

  const [srcWarehouseId, setSrcWarehouseId] = useState<number | null>(null)
  const [destWarehouseId, setDestWarehouseId] = useState<number | null>(null)
  const [srcBinId, setSrcBinId] = useState<number | null>(null)
  const [lines, setLines] = useState<DraftLine[]>([emptyLine()])

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

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

  useEffect(() => {
    if (!srcWarehouseId) {
      setSrcBins([])
      return
    }
    warehousesApi.listBins(srcWarehouseId).then(setSrcBins).catch(() => setSrcBins([]))
  }, [srcWarehouseId])

  useEffect(() => {
    if (!destWarehouseId) {
      setDestBins([])
      return
    }
    warehousesApi.listBins(destWarehouseId).then(setDestBins).catch(() => setDestBins([]))
  }, [destWarehouseId])

  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.length > 1 ? prev.filter((l) => l.key !== key) : prev))
  }

  async function handleSubmit() {
    setSubmitError(null)

    if (!srcWarehouseId || !destWarehouseId) {
      setSubmitError("Select both a source and destination warehouse.")
      return
    }
    if (srcWarehouseId === destWarehouseId) {
      setSubmitError("Source and destination warehouses must be different.")
      return
    }

    const nextLineErrors: Record<string, string> = {}
    for (const line of lines) {
      if (!line.itemId) nextLineErrors[line.key] = "Select an item"
      else if (!line.qty || Number(line.qty) <= 0) nextLineErrors[line.key] = "Quantity must be greater than 0"
    }
    setLineErrors(nextLineErrors)
    if (Object.keys(nextLineErrors).length > 0) {
      setSubmitError("Fix the highlighted lines before submitting.")
      return
    }

    const payloadLines: CreateTransferLineInput[] = lines.map((l) => ({
      itemId: l.itemId as number,
      srcBinId,
      destBinId: l.destBinId,
      qty: Number(l.qty),
    }))

    setSubmitting(true)
    try {
      const transfer = await stockTransfersApi.create({ srcWarehouseId, destWarehouseId, lines: payloadLines })
      toast.success("Transfer created", `${transfer.docNo} is ready to dispatch.`)
      router.push(`/dashboard/stock/transfers/${transfer.transferId}`)
    } catch (err) {
      setSubmitError(errorMessage(err))
      toast.error("Could not create transfer", errorMessage(err))
    } finally {
      setSubmitting(false)
    }
  }

  const loading = !warehouses || !items

  return (
    <div className="flex flex-col gap-6">
      <div className="flex items-center gap-3">
        <div>
          <h1 className="text-2xl font-bold text-foreground">New Transfer</h1>
          <p className="text-base text-muted-foreground">Create a transfer, then dispatch and receive it (FR-STK-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-12 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">From warehouse</Label>
              <Select<number | null> value={srcWarehouseId} onValueChange={(v) => setSrcWarehouseId(v)}>
                <SelectTrigger className="h-12! w-full text-base">
                  <SelectValue placeholder="Select warehouse" />
                </SelectTrigger>
                <SelectContent>
                  {(warehouses ?? []).map((w) => (
                    <SelectItem key={w.warehouseId} value={w.warehouseId} className="text-base">
                      {w.code} — {w.name}
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </div>

            <div className="flex flex-col gap-2">
              <Label className="text-base">From bin (optional)</Label>
              <Select<number | null> value={srcBinId} onValueChange={(v) => setSrcBinId(v)}>
                <SelectTrigger className="h-12! w-full text-base">
                  <SelectValue placeholder="Any bin" />
                </SelectTrigger>
                <SelectContent>
                  {srcBins.map((b) => (
                    <SelectItem key={b.binId} value={b.binId} className="text-base">
                      {b.code}
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </div>

            <div className="flex flex-col gap-2">
              <Label className="text-base">To warehouse</Label>
              <Select<number | null> value={destWarehouseId} onValueChange={(v) => setDestWarehouseId(v)}>
                <SelectTrigger className="h-12! w-full text-base">
                  <SelectValue placeholder="Select warehouse" />
                </SelectTrigger>
                <SelectContent>
                  {(warehouses ?? [])
                    .filter((w) => w.warehouseId !== srcWarehouseId)
                    .map((w) => (
                      <SelectItem key={w.warehouseId} value={w.warehouseId} className="text-base">
                        {w.code} — {w.name}
                      </SelectItem>
                    ))}
                </SelectContent>
              </Select>
            </div>
          </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>

            <Table className="text-base">
              <TableHeader>
                <TableRow>
                  <TableHead className="h-12 w-64 px-3 text-sm">Item</TableHead>
                  <TableHead className="h-12 w-40 px-3 text-sm">Destination bin</TableHead>
                  <TableHead className="h-12 w-32 px-3 text-sm">Qty</TableHead>
                  <TableHead className="h-12 w-10 px-3" />
                </TableRow>
              </TableHeader>
              <TableBody>
                {lines.map((line) => (
                  <TableRow key={line.key}>
                    <TableCell className="px-3 py-3 align-top">
                      <Select<number | null> value={line.itemId} onValueChange={(v) => updateLine(line.key, { itemId: v })}>
                        <SelectTrigger className="h-11! w-full text-base">
                          <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>
                    </TableCell>
                    <TableCell className="px-3 py-3 align-top">
                      <Select<number | null> value={line.destBinId} onValueChange={(v) => updateLine(line.key, { destBinId: v })}>
                        <SelectTrigger className="h-11! w-full text-base">
                          <SelectValue placeholder="None" />
                        </SelectTrigger>
                        <SelectContent>
                          {destBins.map((b) => (
                            <SelectItem key={b.binId} value={b.binId} className="text-base">
                              {b.code}
                            </SelectItem>
                          ))}
                        </SelectContent>
                      </Select>
                    </TableCell>
                    <TableCell className="px-3 py-3 align-top">
                      <Input
                        type="number"
                        min="0"
                        step="any"
                        value={line.qty}
                        aria-invalid={!!lineErrors[line.key]}
                        onChange={(e) => updateLine(line.key, { qty: e.target.value })}
                        className="h-11 text-base"
                      />
                      <FieldError errors={[lineErrors[line.key] ? { message: lineErrors[line.key] } : 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>

          {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/stock/transfers" className={cn(buttonVariants({ variant: "outline", size: "lg" }))}>
              Cancel
            </Link>
            <Button size="lg" type="button" onClick={handleSubmit} disabled={submitting}>
              {submitting ? "Creating…" : "Create Transfer"}
            </Button>
          </div>
        </>
      )}
    </div>
  )
}
