"use client"

import { useEffect, useState } from "react"
import { Ban, CheckCircle2, Pencil, Plus, SwatchBook } from "lucide-react"

import { itemTypesApi } from "@/lib/api/item-types"
import { errorMessage } from "@/lib/error-map"
import { validateItemTypeName } from "@/lib/validations/master-data"
import { ItemType } from "@/types/master-data"

import { AlertDialog, AlertDialogContent, AlertDialogTrigger } from "@/components/ui/alert-dialog"
import { Badge } from "@/components/ui/badge"
import { Switch } from "@/components/ui/switch"
import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import { Field, FieldError, FieldGroup, FieldLabel } from "@/components/ui/field"
import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, DialogTrigger } from "@/components/ui/dialog"
import { Skeleton } from "@/components/ui/skeleton"
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"
import { toast } from "@/components/ui/toast"

/**
 * Item Types (docs/11 §2.7) — the dimension names (Color, Size, Material) the item
 * builder's checkboxes read. Formerly "Variant Categories" in this app.
 *
 * These are names only. The values (Red, S, M) live in each item's generated SKU and are
 * not stored, so nothing here links to an item — renaming a type leaves existing SKUs
 * untouched.
 */
export default function ItemTypesPage() {
  const [itemTypes, setItemTypes] = useState<ItemType[] | null>(null)
  const [error, setError] = useState<string | null>(null)

  const [open, setOpen] = useState(false)
  const [editing, setEditing] = useState<ItemType | null>(null)
  const [name, setName] = useState("")
  const [isMeasurable, setIsMeasurable] = useState(false)
  const [errors, setErrors] = useState<Record<string, string>>({})
  const [submitting, setSubmitting] = useState(false)
  const [togglingId, setTogglingId] = useState<number | null>(null)

  function load() {
    setError(null)
    itemTypesApi
      .list({ pageSize: 200 })
      .then((res) => setItemTypes(res.items))
      .catch((err) => setError(errorMessage(err)))
  }

  useEffect(load, [])

  function openCreateDialog() {
    setEditing(null)
    setName("")
    setIsMeasurable(false)
    setErrors({})
    setOpen(true)
  }

  function openEditDialog(itemType: ItemType) {
    setEditing(itemType)
    setName(itemType.name)
    setIsMeasurable(itemType.isMeasurable)
    setErrors({})
    setOpen(true)
  }

  async function handleSubmit() {
    const nextErrors = validateItemTypeName(name)
    setErrors(nextErrors)
    if (Object.keys(nextErrors).length > 0) return

    setSubmitting(true)
    try {
      if (editing) {
        // Re-read for a fresh If-Match; a concurrent edit surfaces as 412.
        const current = await itemTypesApi.get(editing.itemTypeId)
        // isMeasurable must travel on every PUT: the server preserves it when omitted, so a
        // name-only body would leave the switch the user just flipped unsaved.
        await itemTypesApi.update(editing.itemTypeId, { name, isMeasurable }, current.etag ?? "")
      } else {
        await itemTypesApi.create({ name, isMeasurable })
      }
      toast.success(editing ? "Item type updated" : "Item type created", name)
      setOpen(false)
      setName("")
      setIsMeasurable(false)
      setEditing(null)
      setErrors({})
      load()
    } catch (err) {
      setErrors({ name: errorMessage(err) })
      toast.error(editing ? "Could not update item type" : "Could not create item type", errorMessage(err))
    } finally {
      setSubmitting(false)
    }
  }

  /** Deactivate, never delete — the API has no DELETE (FR-MD-08). */
  async function handleToggleStatus(itemType: ItemType) {
    const next = itemType.status === "Active" ? "Inactive" : "Active"
    setTogglingId(itemType.itemTypeId)
    try {
      await itemTypesApi.updateStatus(itemType.itemTypeId, next)
      toast.success(next === "Inactive" ? "Item type deactivated" : "Item type activated", itemType.name)
      load()
    } catch (err) {
      toast.error("Could not update status", errorMessage(err))
    } finally {
      setTogglingId(null)
    }
  }

  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>
            <h1 className="text-2xl font-bold text-foreground">Item Types</h1>
            <p className="text-base text-muted-foreground">
              Dimensions the item builder offers (e.g. Color, Size, Material). Values are captured per item and encoded in its SKU.
              A <span className="font-medium">measurement</span> dimension captures a number plus a unit instead, which becomes each item&apos;s content size.
            </p>
          </div>
        </div>

        <Dialog open={open} onOpenChange={setOpen}>
          <DialogTrigger render={<Button size="lg" onClick={openCreateDialog}><Plus className="size-5" />Add Item Type</Button>} />
          <DialogContent className="sm:max-w-sm">
            <DialogHeader className="items-center text-center">
              <DialogTitle>{editing ? "Edit item type" : "New item type"}</DialogTitle>
              <DialogDescription>Give the item type a name.</DialogDescription>
            </DialogHeader>
            <FieldGroup>
              <Field data-invalid={!!errors.name}>
                <FieldLabel htmlFor="item-type-name">Name</FieldLabel>
                <Input
                  id="item-type-name"
                  value={name}
                  onChange={(e) => setName(e.target.value)}
                  placeholder="Material"
                  aria-invalid={!!errors.name}
                />
                <FieldError errors={[errors.name ? { message: errors.name } : undefined]} />
              </Field>
              <Field>
                <div className="flex items-start gap-4">
                  <Switch
                    checked={isMeasurable}
                    onCheckedChange={setIsMeasurable}
                    aria-label="Values are measurements"
                    className="mt-1 shrink-0"
                  />
                  <div className="flex flex-col gap-1">
                    <span className="text-base font-medium text-foreground">Values are measurements</span>
                    <span className="text-sm text-muted-foreground">
                      Values are entered as a number plus a unit (500 ml, 1 L) and become each item&apos;s
                      content size. Leave off for plain labels like Red or Small.
                    </span>
                  </div>
                </div>
              </Field>
            </FieldGroup>
            <div className="flex flex-col-reverse gap-3 pt-2 sm:flex-row sm:justify-center">
              <Button variant="outline" className="w-full sm:w-auto sm:min-w-36" onClick={() => setOpen(false)} disabled={submitting}>
                Cancel
              </Button>
              <Button className="w-full sm:w-auto sm:min-w-36" onClick={handleSubmit} disabled={submitting}>
                {submitting ? (editing ? "Saving…" : "Creating…") : editing ? "Save" : "Create"}
              </Button>
            </div>
          </DialogContent>
        </Dialog>
      </div>

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

      {!error && itemTypes === null && (
        <div className="flex flex-col gap-3">
          {Array.from({ length: 3 }).map((_, i) => (
            <Skeleton key={i} className="h-14 w-full" />
          ))}
        </div>
      )}

      {!error && itemTypes !== null && itemTypes.length === 0 && (
        <div className="flex flex-col items-center gap-4 rounded-xl border border-dashed py-20 text-center">
          <SwatchBook className="size-12 text-muted-foreground" />
          <p className="text-base text-muted-foreground">No item types yet.</p>
        </div>
      )}

      {!error && itemTypes !== null && itemTypes.length > 0 && (
        <Table className="text-base">
          <TableHeader>
            <TableRow>
              <TableHead className="h-12 px-3 text-sm">ID</TableHead>
              <TableHead className="h-12 px-3 text-sm">Name</TableHead>
              <TableHead className="h-12 px-3 text-sm">Values</TableHead>
              <TableHead className="h-12 px-3 text-sm">Status</TableHead>
              <TableHead className="h-12 px-3 text-sm">Created At</TableHead>
              <TableHead className="h-12 px-3 text-sm">Actions</TableHead>
            </TableRow>
          </TableHeader>
          <TableBody>
            {itemTypes.map((t) => (
              <TableRow key={t.itemTypeId}>
                <TableCell className="px-3 py-3.5 text-muted-foreground">#{t.itemTypeId}</TableCell>
                <TableCell className="px-3 py-3.5 font-medium">{t.name}</TableCell>
                <TableCell className="px-3 py-3.5">
                  <Badge variant="outline">{t.isMeasurable ? "Measurement" : "Text"}</Badge>
                </TableCell>
                <TableCell className="px-3 py-3.5">
                  <Badge variant={t.status === "Active" ? "default" : "secondary"}>{t.status}</Badge>
                </TableCell>
                <TableCell className="px-3 py-3.5 text-muted-foreground">{new Date(t.createdAt).toLocaleDateString()}</TableCell>
                <TableCell className="px-3 py-3.5">
                  <div className="flex items-center gap-1">
                    <Button variant="ghost" size="icon-sm" aria-label={`Edit ${t.name}`} onClick={() => openEditDialog(t)}>
                      <Pencil className="size-4" />
                    </Button>

                    <AlertDialog>
                      <AlertDialogTrigger
                        render={
                          <Button
                            variant="ghost"
                            size="icon-sm"
                            className={t.status === "Active" ? "text-destructive hover:bg-destructive/10" : ""}
                            aria-label={`${t.status === "Active" ? "Deactivate" : "Activate"} ${t.name}`}
                            disabled={togglingId === t.itemTypeId}
                          />
                        }
                      >
                        {t.status === "Active" ? <Ban className="size-4" /> : <CheckCircle2 className="size-4" />}
                      </AlertDialogTrigger>
                      <AlertDialogContent
                        variant={t.status === "Active" ? "destructive" : "success"}
                        title={`${t.status === "Active" ? "Deactivate" : "Activate"} ${t.name}?`}
                        description={
                          t.status === "Active"
                            ? "It disappears from the item builder. Existing items keep their SKUs — nothing references this record."
                            : "It reappears in the item builder."
                        }
                        confirmLabel={t.status === "Active" ? "Deactivate" : "Activate"}
                        onConfirm={() => handleToggleStatus(t)}
                      />
                    </AlertDialog>
                  </div>
                </TableCell>
              </TableRow>
            ))}
          </TableBody>
        </Table>
      )}
    </div>
  )
}
