"use client"

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

import { stockAdjustmentsApi } from "@/lib/api/stock-adjustments"
import { warehousesApi } from "@/lib/api/warehouses"
import { itemsApi } from "@/lib/api/items"
import { reasonCodesApi } from "@/lib/api/reason-codes"
import { errorMessage } from "@/lib/error-map"
import { cn } from "@/lib/utils"
import { CreateAdjustmentLineInput, ReasonCode, StockAdjustment } from "@/types/stock"
import { 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
  qtyDelta: string
}

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

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

export default function NewAdjustmentPage() {
  const [warehouses, setWarehouses] = useState<Warehouse[] | null>(null)
  const [items, setItems] = useState<ItemListItem[] | null>(null)
  const [reasonCodes, setReasonCodes] = useState<ReasonCode[] | null>(null)
  const [loadError, setLoadError] = useState<string | null>(null)

  const [warehouseId, setWarehouseId] = useState<number | null>(null)
  const [reasonCodeId, setReasonCodeId] = 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)
  const [result, setResult] = useState<StockAdjustment | null>(null)

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

  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 (!warehouseId) {
      setSubmitError("Select a warehouse.")
      return
    }
    if (!reasonCodeId) {
      setSubmitError("A reason code is required for adjustments.")
      return
    }

    const nextLineErrors: Record<string, string> = {}
    for (const line of lines) {
      if (!line.itemId) nextLineErrors[line.key] = "Select an item"
      else if (!line.qtyDelta || Number(line.qtyDelta) === 0) nextLineErrors[line.key] = "Enter a non-zero quantity change"
    }
    setLineErrors(nextLineErrors)
    if (Object.keys(nextLineErrors).length > 0) {
      setSubmitError("Fix the highlighted lines before submitting.")
      return
    }

    const payloadLines: CreateAdjustmentLineInput[] = lines.map((l) => ({
      itemId: l.itemId as number,
      qtyDelta: Number(l.qtyDelta),
    }))

    setSubmitting(true)
    try {
      const adjustment = await stockAdjustmentsApi.create({ warehouseId, reasonCodeId, lines: payloadLines })
      setResult(adjustment)
      toast.success("Adjustment posted", `${adjustment.docNo} posted immediately (auto-post, FR-STK-07).`)
    } catch (err) {
      setSubmitError(errorMessage(err))
      toast.error("Could not post adjustment", errorMessage(err))
    } finally {
      setSubmitting(false)
    }
  }

  function startAnother() {
    setResult(null)
    setLines([emptyLine()])
    setSubmitError(null)
  }

  const loading = !warehouses || !items || !reasonCodes

  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 Adjustment</h1>
          <p className="text-base text-muted-foreground">Posts immediately on creation (FR-STK-07) — a reason code is mandatory.</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 && result && (
        <div className="flex flex-col gap-4">
          <div className="flex flex-col gap-2 rounded-xl border border-success/30 bg-success/5 p-5">
            <div className="flex items-center gap-2 text-success">
              <CheckCircle2 className="size-6" />
              <p className="text-base font-semibold">{result.docNo} posted</p>
            </div>
            <div className="text-sm text-muted-foreground">Ledger refs: {result.ledgerRefs.join(", ")}</div>
          </div>
          <div className="flex gap-3">
            <Link href="/dashboard/stock/adjustments" className={cn(buttonVariants({ variant: "outline", size: "lg" }))}>
              Back to list
            </Link>
            <Button size="lg" type="button" onClick={startAnother}>
              New adjustment
            </Button>
          </div>
        </div>
      )}

      {!loading && !result && (
        <>
          <div className="grid grid-cols-1 gap-4 sm:grid-cols-2">
            <div className="flex flex-col gap-2">
              <Label className="text-base">Warehouse</Label>
              <Select<number | null> value={warehouseId} onValueChange={(v) => setWarehouseId(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">Reason code</Label>
              <Select<number | null> value={reasonCodeId} onValueChange={(v) => setReasonCodeId(v)}>
                <SelectTrigger className="h-12! w-full text-base">
                  <SelectValue placeholder="Select reason" />
                </SelectTrigger>
                <SelectContent>
                  {(reasonCodes ?? []).map((r) => (
                    <SelectItem key={r.reasonCodeId} value={r.reasonCodeId} className="text-base">
                      {r.description}
                    </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-72 px-3 text-sm">Item</TableHead>
                  <TableHead className="h-12 w-40 px-3 text-sm">Qty change</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">
                      <Input
                        type="number"
                        step="any"
                        placeholder="e.g. -15 or 50"
                        value={line.qtyDelta}
                        aria-invalid={!!lineErrors[line.key]}
                        onChange={(e) => updateLine(line.key, { qtyDelta: 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/adjustments" className={cn(buttonVariants({ variant: "outline", size: "lg" }))}>
              Cancel
            </Link>
            <Button size="lg" type="button" onClick={handleSubmit} disabled={submitting}>
              {submitting ? "Posting…" : "Post Adjustment"}
            </Button>
          </div>
        </>
      )}
    </div>
  )
}
