"use client"

import { useEffect, useState } from "react"
import { useParams, useRouter } from "next/navigation"
import Link from "next/link"
import { AlertTriangle, Save } from "lucide-react"

import { vendorsApi } from "@/lib/api/vendors"
import { errorMessage, fieldErrors } from "@/lib/error-map"
import { cn } from "@/lib/utils"
import { generateVendorCode } from "@/lib/vendor-code"
import { 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 { Badge } from "@/components/ui/badge"
import { Skeleton } from "@/components/ui/skeleton"
import { toast } from "@/components/ui/toast"

export default function VendorDetailPage() {
  const params = useParams<{ id: string }>()
  const router = useRouter()
  const vendorId = Number(params.id)

  const [vendor, setVendor] = useState<Vendor | null>(null)
  const [etag, setEtag] = useState<string | null>(null)
  const [loadError, setLoadError] = useState<string | null>(null)

  const [code, setCode] = useState("")
  const [name, setName] = useState("")
  const [terms, setTerms] = useState("")
  const [taxReg, setTaxReg] = useState("")
  const [currency, setCurrency] = useState("")

  const [errors, setErrors] = useState<Record<string, string>>({})
  const [conflict, setConflict] = useState(false)
  const [saveError, setSaveError] = useState<string | null>(null)
  const [saving, setSaving] = useState(false)
  const [togglingStatus, setTogglingStatus] = useState(false)

  // Every other vendor's code, to de-dupe against when the name edit regenerates this
  // vendor's own code (mirrors the create dialog's `allVendorCodes`, app/dashboard/vendors/page.tsx).
  const [otherVendorCodes, setOtherVendorCodes] = useState<string[]>([])

  useEffect(() => {
    vendorsApi
      .list({ pageSize: 200 })
      .then((res) => setOtherVendorCodes(res.items.filter((v) => v.vendorId !== vendorId).map((v) => v.code)))
      .catch(() => {})
  }, [vendorId])

  function handleNameChange(value: string) {
    setName(value)
    setCode(value.trim() ? generateVendorCode(value, otherVendorCodes) : "")
  }

  function load() {
    setLoadError(null)
    vendorsApi
      .get(vendorId)
      .then(({ data, etag: tag }) => {
        setVendor(data)
        setEtag(tag)
        setCode(data.code)
        setName(data.name)
        setTerms(data.terms ?? "")
        setTaxReg(data.taxReg ?? "")
        setCurrency(data.currency)
        setConflict(false)
      })
      .catch((err) => setLoadError(errorMessage(err)))
  }

  useEffect(() => {
    if (Number.isFinite(vendorId)) load()
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [vendorId])

  async function handleSave() {
    setSaveError(null)
    const nextErrors: Record<string, string> = {}
    if (!code.trim()) nextErrors.code = "Vendor code is required"
    if (!name.trim()) nextErrors.name = "Vendor name is required"
    if (!currency.trim()) nextErrors.currency = "Currency is required"
    setErrors(nextErrors)
    if (Object.keys(nextErrors).length > 0 || !etag) return

    setSaving(true)
    try {
      const result = await vendorsApi.update(vendorId, { code, name, terms: terms || null, taxReg: taxReg || null, currency }, etag)
      setVendor(result.data)
      setEtag(result.etag)
      toast.success("Vendor saved", `${result.data.code} — ${result.data.name}`)
    } catch (err) {
      const code = (err as { code?: string })?.code
      if (code === "CONCURRENCY_CONFLICT") {
        setConflict(true)
        setSaveError(errorMessage(err))
        setSaving(false)
        return
      }
      const fe = fieldErrors(err)
      if (fe?.code) setErrors({ code: fe.code })
      setSaveError(errorMessage(err))
      toast.error("Could not save vendor", errorMessage(err))
    } finally {
      setSaving(false)
    }
  }

  async function handleToggleStatus() {
    if (!vendor) return
    const next = vendor.status === "Active" ? "Inactive" : "Active"
    setTogglingStatus(true)
    try {
      await vendorsApi.updateStatus(vendorId, next)
      toast.success(next === "Active" ? "Vendor activated" : "Vendor deactivated")
      load()
    } catch (err) {
      toast.error("Could not update status", errorMessage(err))
    } finally {
      setTogglingStatus(false)
    }
  }

  if (loadError && !vendor) {
    return (
      <div className="flex flex-col gap-4">
        <div className="rounded-lg border border-destructive/30 bg-destructive/5 p-5 text-base text-destructive">{loadError}</div>
        <Link href="/dashboard/vendors" className={cn(buttonVariants({ variant: "outline" }))}>
          Back to vendors
        </Link>
      </div>
    )
  }

  if (!vendor) {
    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 flex-col gap-3 sm:flex-row sm:items-center sm:justify-between">
        <div className="flex items-center gap-3">
          <div>
            <div className="flex items-center gap-3">
              <h1 className="text-2xl font-bold text-foreground">{vendor.code}</h1>
              <Badge
                variant="outline"
                className={cn(
                  "h-6 w-fit justify-center border-transparent px-2.5 text-sm",
                  vendor.status === "Active" ? "bg-success/10 text-success" : "bg-muted text-muted-foreground"
                )}
              >
                {vendor.status}
              </Badge>
            </div>
            <p className="text-base text-muted-foreground">{vendor.name}</p>
          </div>
        </div>

        <Button
          size="lg"
          variant={vendor.status === "Active" ? "destructive" : "success"}
          onClick={handleToggleStatus}
          disabled={togglingStatus}
        >
          {togglingStatus ? "Updating…" : vendor.status === "Active" ? "Deactivate" : "Activate"}
        </Button>
      </div>

      {conflict && (
        <div className="flex items-start gap-3 rounded-lg border border-warning/30 bg-warning/5 p-5 text-base text-warning">
          <AlertTriangle className="size-5 shrink-0" />
          <div className="flex flex-col gap-2">
            <p>{saveError ?? "This vendor was changed by someone else."} Reload before retrying.</p>
            <Button size="sm" variant="outline" onClick={load}>
              Reload
            </Button>
          </div>
        </div>
      )}

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

      <div className="grid grid-cols-1 gap-4 sm:grid-cols-2">
        <div className="flex flex-col gap-2">
          <Label className="text-base">Code (auto-generated)</Label>
          <Input value={code} readOnly disabled className="h-12 text-base text-muted-foreground" />
          <FieldError errors={[errors.code ? { message: errors.code } : undefined]} />
        </div>
        <div className="flex flex-col gap-2">
          <Label className="text-base">Name</Label>
          <Input value={name} onChange={(e) => handleNameChange(e.target.value)} aria-invalid={!!errors.name} className="h-12 text-base" disabled={conflict} />
          <FieldError errors={[errors.name ? { message: errors.name } : undefined]} />
        </div>
        <div className="flex flex-col gap-2">
          <Label className="text-base">Payment terms</Label>
          <Input value={terms} onChange={(e) => setTerms(e.target.value)} placeholder="NET30" className="h-12 text-base" disabled={conflict} />
        </div>
        <div className="flex flex-col gap-2">
          <Label className="text-base">Tax registration</Label>
          <Input value={taxReg} onChange={(e) => setTaxReg(e.target.value)} className="h-12 text-base" disabled={conflict} />
        </div>
        <div className="flex flex-col gap-2">
          <Label className="text-base">Currency</Label>
          <Input value={currency} onChange={(e) => setCurrency(e.target.value)} maxLength={3} aria-invalid={!!errors.currency} className="h-12 text-base" disabled={conflict} />
          <FieldError errors={[errors.currency ? { message: errors.currency } : undefined]} />
        </div>
      </div>

      <div className="flex justify-end gap-3">
        <Button variant="outline" size="lg" onClick={() => router.push("/dashboard/vendors")}>
          Cancel
        </Button>
        <Button size="lg" onClick={handleSave} disabled={saving || conflict}>
          <Save className="size-5" />
          {saving ? "Saving…" : "Save changes"}
        </Button>
      </div>
    </div>
  )
}
