"use client"

import { useEffect, useMemo, useState } from "react"
import { useParams } from "next/navigation"
import Link from "next/link"
import { ShoppingCart } from "lucide-react"

import { rfqsApi } from "@/lib/api/rfqs"
import { vendorsApi } from "@/lib/api/vendors"
import { itemsApi } from "@/lib/api/items"
import { errorMessage } from "@/lib/error-map"
import { validateQuotationLine } from "@/lib/validations/procurement"
import { cn } from "@/lib/utils"
import { QuotationLine, Rfq, RfqComparison } 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 { 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"
import { RfqStatusBadge } from "@/components/procurement/status-badges"

interface QuoteDraft {
  unitPrice: string
  leadDays: string
}

export default function RfqDetailPage() {
  const params = useParams<{ id: string }>()
  const rfqId = Number(params.id)

  const [rfq, setRfq] = useState<Rfq | null>(null)
  const [comparison, setComparison] = useState<RfqComparison | null>(null)
  const [items, setItems] = useState<ItemListItem[]>([])
  const [vendors, setVendors] = useState<Vendor[]>([])
  const [error, setError] = useState<string | null>(null)

  const [quoteVendorId, setQuoteVendorId] = useState<number | null>(null)
  const [quoteLines, setQuoteLines] = useState<Record<number, QuoteDraft>>({})
  const [quoteErrors, setQuoteErrors] = useState<Record<number, Record<string, string>>>({})
  const [quoteFormError, setQuoteFormError] = useState<string | null>(null)
  const [submittingQuote, setSubmittingQuote] = useState(false)

  function load() {
    setError(null)
    Promise.all([rfqsApi.get(rfqId), rfqsApi.comparison(rfqId)])
      .then(([r, c]) => {
        setRfq(r)
        setComparison(c)
      })
      .catch((err) => setError(errorMessage(err)))
  }

  useEffect(() => {
    if (!Number.isFinite(rfqId)) return
    load()
    Promise.all([itemsApi.list({ pageSize: 200 }), vendorsApi.list({ pageSize: 200 })])
      .then(([it, ve]) => {
        setItems(it.items)
        setVendors(ve.items)
      })
      .catch(() => {})
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [rfqId])

  const quotedVendorIds = useMemo(() => {
    const set = new Set<number>()
    for (const row of comparison?.rows ?? []) for (const quote of row.quotes) set.add(quote.vendorId)
    return set
  }, [comparison])

  /**
   * Vendors still available to quote.
   *
   * This used to be "invited but not yet quoted", but the invited list does not survive:
   * `POST /rfqs` validates `vendorIds` and then discards them — there is no RFQ↔vendor
   * link in the model (docs/11 §3.2). So any active vendor may be quoted here, and the
   * comparison's columns come from who actually quoted rather than who was asked.
   */
  const pendingVendors = useMemo(
    () => vendors.filter((v) => v.status === "Active" && !quotedVendorIds.has(v.vendorId)).map((v) => v.vendorId),
    [vendors, quotedVendorIds],
  )

  function itemFor(itemId: number) {
    return items.find((i) => i.itemId === itemId)
  }
  function vendorFor(vendorId: number) {
    return vendors.find((v) => v.vendorId === vendorId)
  }

  function selectQuoteVendor(vendorId: number | null) {
    setQuoteVendorId(vendorId)
    setQuoteFormError(null)
    setQuoteErrors({})
    if (!rfq) return
    const draft: Record<number, QuoteDraft> = {}
    for (const line of rfq.lines) draft[line.itemId] = { unitPrice: "", leadDays: "" }
    setQuoteLines(draft)
  }

  async function handleSubmitQuote() {
    if (!rfq || !quoteVendorId) {
      setQuoteFormError("Select a vendor first.")
      return
    }
    const nextErrors: Record<number, Record<string, string>> = {}
    for (const line of rfq.lines) {
      const draft = quoteLines[line.itemId] ?? { unitPrice: "", leadDays: "" }
      const errors = validateQuotationLine(draft)
      if (Object.keys(errors).length > 0) nextErrors[line.itemId] = errors
    }
    setQuoteErrors(nextErrors)
    if (Object.keys(nextErrors).length > 0) {
      setQuoteFormError("Fix the highlighted fields before submitting.")
      return
    }

    const lines: QuotationLine[] = rfq.lines.map((l) => ({
      itemId: l.itemId,
      unitPrice: Number(quoteLines[l.itemId].unitPrice),
      leadDays: Number(quoteLines[l.itemId].leadDays),
    }))

    setSubmittingQuote(true)
    try {
      await rfqsApi.addQuotation(rfqId, { vendorId: quoteVendorId, lines })
      toast.success("Quotation recorded", `${vendorFor(quoteVendorId)?.code ?? `Vendor #${quoteVendorId}`} priced ${lines.length} line(s).`)
      setQuoteVendorId(null)
      setQuoteLines({})
      const c = await rfqsApi.comparison(rfqId)
      setComparison(c)
    } catch (err) {
      setQuoteFormError(errorMessage(err))
      toast.error("Could not record quotation", errorMessage(err))
    } finally {
      setSubmittingQuote(false)
    }
  }

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

  if (!rfq || !comparison) {
    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 gap-3">
        <div>
          <div className="flex items-center gap-3">
            <h1 className="text-2xl font-bold text-foreground">{rfq.docNo}</h1>
            <RfqStatusBadge status={rfq.status} />
          </div>
          {/* No "Invited: …" — the invited-vendor list is not persisted (docs/11 §3.2). */}
          <p className="text-base text-muted-foreground">
            {rfq.requisitionId ? `From Requisition #${rfq.requisitionId}` : ""}
          </p>
        </div>
      </div>

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

      <div className="flex flex-col gap-3">
        <h2 className="text-base font-semibold text-foreground">Lines</h2>
        <Table className="text-base">
          <TableHeader>
            <TableRow>
              <TableHead className="h-12 px-3 text-sm">Item</TableHead>
              <TableHead className="h-12 px-3 text-sm">Qty</TableHead>
            </TableRow>
          </TableHeader>
          <TableBody>
            {rfq.lines.map((line) => {
              const item = itemFor(line.itemId)
              return (
                <TableRow key={line.rfqLineId}>
                  <TableCell className="px-3 py-3.5">{item ? `${item.sku} — ${item.name}` : `Item #${line.itemId}`}</TableCell>
                  <TableCell className="px-3 py-3.5">{line.qty}</TableCell>
                </TableRow>
              )
            })}
          </TableBody>
        </Table>
      </div>

      <div className="flex flex-col gap-3">
        <h2 className="text-base font-semibold text-foreground">Vendor comparison</h2>
        {comparison.rows.every((r) => r.quotes.length === 0) ? (
          <p className="text-base text-muted-foreground">No quotations recorded yet.</p>
        ) : (
          <div className="overflow-x-auto">
            <Table className="text-base">
              <TableHeader>
                <TableRow>
                  <TableHead className="h-12 px-3 text-sm">Item</TableHead>
                  {/* Columns are the vendors that actually quoted — the server computes this. */}
                  {comparison.vendorIds.map((vid) => (
                    <TableHead key={vid} className="h-12 px-3 text-sm">{vendorFor(vid)?.code ?? `#${vid}`}</TableHead>
                  ))}
                </TableRow>
              </TableHeader>
              <TableBody>
                {comparison.rows.map((line) => {
                  const item = itemFor(line.itemId)
                  return (
                    <TableRow key={line.itemId}>
                      <TableCell className="px-3 py-3.5">{item ? `${item.sku} — ${item.name}` : `Item #${line.itemId}`}</TableCell>
                      {comparison.vendorIds.map((vid) => {
                        const cell = line.quotes.find((c) => c.vendorId === vid)
                        return (
                          <TableCell key={vid} className="px-3 py-3.5">
                            {cell ? (
                              <span>
                                {cell.unitPrice.toFixed(2)} <span className="text-sm text-muted-foreground">({cell.leadDays}d)</span>
                              </span>
                            ) : (
                              <span className="text-sm text-muted-foreground">—</span>
                            )}
                          </TableCell>
                        )
                      })}
                    </TableRow>
                  )
                })}
              </TableBody>
            </Table>
          </div>
        )}

        {[...quotedVendorIds].length > 0 && (
          <div className="flex flex-wrap gap-2">
            {[...quotedVendorIds].map((vid) => (
              <Link
                key={vid}
                href={`/dashboard/procurement/purchase-orders/new?rfqId=${rfqId}&vendorId=${vid}`}
                className={cn(buttonVariants({ variant: "outline", size: "sm" }))}
              >
                <ShoppingCart className="size-4" />
                Create PO from {vendorFor(vid)?.code ?? `#${vid}`}
              </Link>
            ))}
          </div>
        )}
      </div>

      {pendingVendors.length > 0 && (
        <div className="flex flex-col gap-3 rounded-xl border p-5">
          <h2 className="text-base font-semibold text-foreground">Record a quotation</h2>

          <div className="flex flex-col gap-2 sm:w-72">
            <Label className="text-base">Vendor</Label>
            <Select<number | null> value={quoteVendorId} onValueChange={selectQuoteVendor}>
              <SelectTrigger className="h-11! w-full text-base">
                <SelectValue placeholder="Select a vendor" />
              </SelectTrigger>
              <SelectContent>
                {pendingVendors.map((vid) => (
                  <SelectItem key={vid} value={vid} className="text-base">
                    {vendorFor(vid)?.code ?? `#${vid}`} — {vendorFor(vid)?.name}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
          </div>

          {quoteVendorId && (
            <Table className="text-base">
              <TableHeader>
                <TableRow>
                  <TableHead className="h-12 px-3 text-sm">Item</TableHead>
                  <TableHead className="h-12 w-36 px-3 text-sm">Unit price</TableHead>
                  <TableHead className="h-12 w-32 px-3 text-sm">Lead days</TableHead>
                </TableRow>
              </TableHeader>
              <TableBody>
                {rfq.lines.map((line) => {
                  const item = itemFor(line.itemId)
                  const draft = quoteLines[line.itemId] ?? { unitPrice: "", leadDays: "" }
                  const errors = quoteErrors[line.itemId] ?? {}
                  return (
                    <TableRow key={line.rfqLineId}>
                      <TableCell className="px-3 py-3.5">{item ? `${item.sku} — ${item.name}` : `Item #${line.itemId}`}</TableCell>
                      <TableCell className="px-3 py-3 align-top">
                        <Input
                          type="number"
                          min="0"
                          step="any"
                          value={draft.unitPrice}
                          aria-invalid={!!errors.unitPrice}
                          onChange={(e) => setQuoteLines((prev) => ({ ...prev, [line.itemId]: { ...prev[line.itemId], unitPrice: e.target.value } }))}
                          className="h-11 text-base"
                        />
                        <FieldError errors={[errors.unitPrice ? { message: errors.unitPrice } : undefined]} />
                      </TableCell>
                      <TableCell className="px-3 py-3 align-top">
                        <Input
                          type="number"
                          min="0"
                          step="1"
                          value={draft.leadDays}
                          aria-invalid={!!errors.leadDays}
                          onChange={(e) => setQuoteLines((prev) => ({ ...prev, [line.itemId]: { ...prev[line.itemId], leadDays: e.target.value } }))}
                          className="h-11 text-base"
                        />
                        <FieldError errors={[errors.leadDays ? { message: errors.leadDays } : undefined]} />
                      </TableCell>
                    </TableRow>
                  )
                })}
              </TableBody>
            </Table>
          )}

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

          <div className="flex justify-end">
            <Button type="button" onClick={handleSubmitQuote} disabled={!quoteVendorId || submittingQuote}>
              {submittingQuote ? "Saving…" : "Save quotation"}
            </Button>
          </div>
        </div>
      )}
    </div>
  )
}
