"use client"

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

import { rfqsApi } from "@/lib/api/rfqs"
import { requisitionsApi } from "@/lib/api/requisitions"
import { vendorsApi } from "@/lib/api/vendors"
import { itemsApi } from "@/lib/api/items"
import { errorMessage } from "@/lib/error-map"
import { validateRfqLine } from "@/lib/validations/procurement"
import { cn } from "@/lib/utils"
import { CreateRfqLineInput } from "@/types/procurement"
import { ItemListItem, Vendor } from "@/types/master-data"

import { Button, buttonVariants } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"
import { Checkbox } from "@/components/ui/checkbox"
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
  qty: string
}

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

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

function NewRfqContent() {
  const router = useRouter()
  const searchParams = useSearchParams()
  const requisitionId = Number(searchParams.get("requisitionId")) || null

  const [items, setItems] = useState<ItemListItem[] | null>(null)
  const [vendors, setVendors] = useState<Vendor[] | null>(null)
  const [loadError, setLoadError] = useState<string | null>(null)
  const [requisitionLoading, setRequisitionLoading] = useState(!!requisitionId)

  const [vendorIds, setVendorIds] = useState<Set<number>>(new Set())
  const [lines, setLines] = useState<DraftLine[]>([emptyLine()])
  const [lineErrors, setLineErrors] = useState<Record<string, Record<string, string>>>({})
  const [headerError, setHeaderError] = useState<string | null>(null)
  const [submitError, setSubmitError] = useState<string | null>(null)
  const [submitting, setSubmitting] = useState(false)

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

  useEffect(() => {
    if (!requisitionId) return
    requisitionsApi
      .get(requisitionId)
      .then((req) => {
        setLines(req.lines.map((l): DraftLine => ({ key: newKey(), itemId: l.itemId, qty: String(l.qty) })))
      })
      .catch((err) => setHeaderError(errorMessage(err)))
      .finally(() => setRequisitionLoading(false))
  }, [requisitionId])

  function toggleVendor(vendorId: number) {
    setVendorIds((prev) => {
      const next = new Set(prev)
      if (next.has(vendorId)) next.delete(vendorId)
      else next.add(vendorId)
      return next
    })
  }

  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))
  }

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

    // The server requires a requisition — an RFQ is always raised against one
    // (docs/11 §3.2). Catch it here rather than letting the POST 400.
    if (requisitionId === null) {
      setHeaderError("Select the requisition this RFQ is raised against.")
      return
    }
    if (vendorIds.size === 0) {
      setHeaderError("Select at least one vendor to invite.")
      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 = validateRfqLine({ itemId: line.itemId, qty: line.qty })
      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: CreateRfqLineInput[] = lines.map((l) => ({ itemId: l.itemId as number, qty: Number(l.qty) }))

    setSubmitting(true)
    try {
      const rfq = await rfqsApi.create({ requisitionId, vendorIds: [...vendorIds], lines: payloadLines })
      toast.success("RFQ created", `${rfq.docNo} sent to ${vendorIds.size} vendor(s).`)
      router.push(`/dashboard/procurement/rfqs/${rfq.rfqId}`)
    } catch (err) {
      setSubmitError(errorMessage(err))
      toast.error("Could not create RFQ", errorMessage(err))
    } finally {
      setSubmitting(false)
    }
  }

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

  const loading = !items || !vendors || requisitionLoading

  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 RFQ</h1>
          <p className="text-base text-muted-foreground">
            {requisitionId ? `Request quotations for Requisition #${requisitionId}` : "Request quotations from one or more vendors (FR-PROC-02)."}
          </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="flex flex-col gap-2">
            <Label className="text-base">Invite vendors</Label>
            <div className="grid grid-cols-1 gap-1 rounded-xl border p-3 sm:grid-cols-2">
              {(vendors ?? []).map((v) => (
                <label key={v.vendorId} className="flex items-center gap-3 rounded-lg px-3 py-2.5 hover:bg-muted/50">
                  <Checkbox checked={vendorIds.has(v.vendorId)} onCheckedChange={() => toggleVendor(v.vendorId)} />
                  <span className="text-base font-medium">{v.code}</span>
                  <span className="text-sm text-muted-foreground">{v.name}</span>
                </label>
              ))}
            </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>
              {!requisitionId && (
                <Button type="button" variant="outline" onClick={() => setLines((prev) => [...prev, emptyLine()])}>
                  <Plus className="size-5" />
                  Add line
                </Button>
              )}
            </div>

            {lines.length > 0 && (
              <Table className="text-base">
                <TableHeader>
                  <TableRow>
                    <TableHead className="h-12 w-72 px-3 text-sm">Item</TableHead>
                    <TableHead className="h-12 w-32 px-3 text-sm">Qty</TableHead>
                    {!requisitionId && <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 ? (
                            <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">
                          <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>
                        {!requisitionId && (
                          <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/procurement/rfqs" className={cn(buttonVariants({ variant: "outline", size: "lg" }))}>
              Cancel
            </Link>
            <Button size="lg" type="button" onClick={handleSubmit} disabled={submitting}>
              {submitting ? "Sending…" : "Create RFQ"}
            </Button>
          </div>
        </>
      )}
    </div>
  )
}

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