"use client"

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

import { isWastageReasonCode, wastageApi } from "@/lib/api/wastage"
import { reasonCodesApi } from "@/lib/api/reason-codes"
import { warehousesApi } from "@/lib/api/warehouses"
import { itemsApi } from "@/lib/api/items"
import { stockApi } from "@/lib/api/stock"
import { errorMessage } from "@/lib/error-map"
import { cn } from "@/lib/utils"
import { OnHand, ReasonCode, StockAdjustment } 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 { Skeleton } from "@/components/ui/skeleton"
import { toast } from "@/components/ui/toast"

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

  const [warehouseId, setWarehouseId] = useState<number | null>(null)
  const [itemId, setItemId] = useState<number | null>(null)
  const [binId, setBinId] = useState<number | null>(null)
  const [qty, setQty] = useState("")
  const [reasonCodeId, setReasonCodeId] = useState<number | null>(null)

  const [onHand, setOnHand] = useState<OnHand | null>(null)
  const [onHandLoading, setOnHandLoading] = useState(false)
  const [onHandError, setOnHandError] = useState<string | null>(null)

  const [errors, setErrors] = useState<Record<string, string>>({})
  const [submitError, setSubmitError] = useState<string | null>(null)
  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.filter((r) => isWastageReasonCode(r.code)))
      })
      .catch((err) => setLoadError(errorMessage(err)))
  }, [])

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

  useEffect(() => {
    if (!itemId || !warehouseId) {
      setOnHand(null)
      setOnHandError(null)
      return
    }
    setOnHandLoading(true)
    setOnHandError(null)
    stockApi
      .onHand(itemId, warehouseId)
      .then(setOnHand)
      .catch((err) => {
        setOnHand(null)
        setOnHandError(errorMessage(err))
      })
      .finally(() => setOnHandLoading(false))
  }, [itemId, warehouseId])

  async function handleSubmit() {
    setSubmitError(null)
    const nextErrors: Record<string, string> = {}
    if (!warehouseId) nextErrors.warehouseId = "Select a warehouse"
    if (!itemId) nextErrors.itemId = "Select an item"
    if (!qty || Number(qty) <= 0) nextErrors.qty = "Quantity must be greater than 0"
    else if (onHand && Number(qty) > onHand.available) nextErrors.qty = `Insufficient quantity — only ${onHand.available} available`
    if (!reasonCodeId) nextErrors.reasonCodeId = "Select a wastage reason"
    setErrors(nextErrors)
    if (Object.keys(nextErrors).length > 0) return

    setSubmitting(true)
    try {
      const adjustment = await wastageApi.record({
        warehouseId: warehouseId as number,
        itemId: itemId as number,
        binId,
        qty: Number(qty),
        reasonCodeId: reasonCodeId as number,
      })
      setResult(adjustment)
      toast.success("Wastage recorded", `${adjustment.docNo} posted immediately (auto-post, FR-STK-07).`)
    } catch (err) {
      setSubmitError(errorMessage(err))
      toast.error("Could not record wastage", errorMessage(err))
    } finally {
      setSubmitting(false)
    }
  }

  function startAnother() {
    setResult(null)
    setItemId(null)
    setQty("")
    setReasonCodeId(null)
    setSubmitError(null)
    setOnHand(null)
    setOnHandError(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">Record Wastage</h1>
          <p className="text-base text-muted-foreground">Posts immediately as a stock adjustment (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/wastage" className={cn(buttonVariants({ variant: "outline", size: "lg" }))}>
              Back to wastage report
            </Link>
            <Button size="lg" type="button" onClick={startAnother}>
              Record another
            </Button>
          </div>
        </div>
      )}

      {!loading && !result && (
        <>
          {(reasonCodes ?? []).length === 0 && (
            <div className="flex items-center gap-2 rounded-lg border border-warning/30 bg-warning/5 p-4 text-base text-warning">
              <AlertOctagon className="size-5" />
              No wastage-type reason codes (Damage / Theft-Loss / Expiry Write-off) are configured.
            </div>
          )}

          <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>
              <FieldError errors={[errors.warehouseId ? { message: errors.warehouseId } : undefined]} />
            </div>

            <div className="flex flex-col gap-2">
              <Label className="text-base">Bin (optional)</Label>
              <Select<number | null> value={binId} onValueChange={(v) => setBinId(v)}>
                <SelectTrigger className="h-12! w-full text-base">
                  <SelectValue placeholder="None" />
                </SelectTrigger>
                <SelectContent>
                  {bins.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">Item</Label>
              <Select<number | null> value={itemId} onValueChange={(v) => setItemId(v)}>
                <SelectTrigger className="h-12! 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>
              <FieldError errors={[errors.itemId ? { message: errors.itemId } : undefined]} />
            </div>

            <div className="flex flex-col gap-2">
              <div className="flex items-center justify-between">
                <Label className="text-base">Quantity wasted</Label>
                {itemId && warehouseId && (
                  <span className="text-sm text-muted-foreground">
                    {onHandLoading
                      ? "Checking available stock…"
                      : onHandError
                        ? "Available stock unknown"
                        : onHand
                          ? `Available: ${onHand.available}`
                          : null}
                  </span>
                )}
              </div>
              <Input
                type="number"
                min="0"
                step="any"
                value={qty}
                aria-invalid={!!errors.qty}
                onChange={(e) => setQty(e.target.value)}
                className="h-12 text-base"
              />
              <FieldError errors={[errors.qty ? { message: errors.qty } : undefined]} />
            </div>

            <div className="flex flex-col gap-2 sm:col-span-2">
              <Label className="text-base">Reason</Label>
              <Select<number | null> value={reasonCodeId} onValueChange={(v) => setReasonCodeId(v)}>
                <SelectTrigger className="h-12! w-full text-base">
                  <SelectValue placeholder="Select a wastage reason" />
                </SelectTrigger>
                <SelectContent>
                  {(reasonCodes ?? []).map((r) => (
                    <SelectItem key={r.reasonCodeId} value={r.reasonCodeId} className="text-base">
                      {r.description}
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
              <FieldError errors={[errors.reasonCodeId ? { message: errors.reasonCodeId } : undefined]} />
            </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/stock/wastage" className={cn(buttonVariants({ variant: "outline", size: "lg" }))}>
              Cancel
            </Link>
            <Button size="lg" variant="destructive" type="button" onClick={handleSubmit} disabled={submitting}>
              {submitting ? "Recording…" : "Record Wastage"}
            </Button>
          </div>
        </>
      )}
    </div>
  )
}
