"use client";

import { useState } from "react";
import { useRouter } from "next/navigation";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Textarea } from "@/components/ui/textarea";
import {
  Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter,
} from "@/components/ui/dialog";
import {
  Select, SelectContent, SelectItem, SelectTrigger, SelectValue,
} from "@/components/ui/select";
import { Badge } from "@/components/ui/badge";
import { useToast } from "@/hooks/use-toast";
import { Plus, Pencil } from "lucide-react";

export type LocationOpt = { id: string; name: string };
export type ItemOpt = { id: string; name: string };
export type LabelOpt = { id: string; name: string; color: string | null };

export type ItemFields = {
  id?: string;
  name: string;
  description: string;
  quantity: string;
  unit: string;
  locationId: string;
  parentItemId: string;
  brand: string;
  modelNumber: string;
  serial: string;
  value: string;
  purchaseDate: string;
  purchaseFrom: string;
  warrantyExpiry: string;
  warrantyDetails: string;
  lifetimeWarranty: boolean;
  insured: boolean;
  barcode: string;
  notes: string;
  labelIds: string[];
};

export function blankItem(): ItemFields {
  return {
    name: "", description: "", quantity: "1", unit: "", locationId: "", parentItemId: "",
    brand: "", modelNumber: "", serial: "", value: "", purchaseDate: "", purchaseFrom: "",
    warrantyExpiry: "", warrantyDetails: "", lifetimeWarranty: false, insured: false,
    barcode: "", notes: "", labelIds: [],
  };
}

const NONE = "__none__";

function ItemDialog({
  trigger, title, initial, locations, items, labels: initialLabels,
}: {
  trigger: React.ReactNode;
  title: string;
  initial: ItemFields;
  locations: LocationOpt[];
  items: ItemOpt[];
  labels: LabelOpt[];
}) {
  const [open, setOpen] = useState(false);
  const [f, setF] = useState<ItemFields>(initial);
  const [labels, setLabels] = useState<LabelOpt[]>(initialLabels);
  const [newLabel, setNewLabel] = useState("");
  const [busy, setBusy] = useState(false);
  const [error, setError] = useState("");
  const router = useRouter();
  const { toast } = useToast();

  function set<K extends keyof ItemFields>(k: K, v: ItemFields[K]) {
    setF((p) => ({ ...p, [k]: v }));
  }
  function toggleLabel(id: string) {
    setF((p) => ({ ...p, labelIds: p.labelIds.includes(id) ? p.labelIds.filter((x) => x !== id) : [...p.labelIds, id] }));
  }
  async function addLabel() {
    const name = newLabel.trim();
    if (!name) return;
    const res = await fetch("/api/v1/labels", {
      method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ name }),
    });
    if (res.ok) {
      const lab = await res.json();
      setLabels((p) => (p.some((l) => l.id === lab.id) ? p : [...p, lab]));
      toggleLabel(lab.id);
      setNewLabel("");
    }
  }

  // Items selectable as a parent — exclude self.
  const parentOptions = items.filter((i) => i.id !== f.id);

  async function submit(e: React.FormEvent) {
    e.preventDefault();
    if (!f.name.trim()) { setError("Please give the item a name."); return; }
    setError("");
    setBusy(true);

    const payload = {
      name: f.name.trim(),
      description: f.description.trim() || undefined,
      quantity: f.quantity ? Number(f.quantity) : undefined,
      unit: f.unit.trim() || undefined,
      locationId: f.locationId || null,
      parentItemId: f.parentItemId || null,
      brand: f.brand.trim() || undefined,
      modelNumber: f.modelNumber.trim() || undefined,
      serial: f.serial.trim() || undefined,
      value: f.value ? Number(f.value) : null,
      purchaseDate: f.purchaseDate || null,
      purchaseFrom: f.purchaseFrom.trim() || undefined,
      warrantyExpiry: f.warrantyExpiry || null,
      warrantyDetails: f.warrantyDetails.trim() || undefined,
      lifetimeWarranty: f.lifetimeWarranty,
      insured: f.insured,
      barcode: f.barcode.trim() || undefined,
      notes: f.notes.trim() || undefined,
      labelIds: f.labelIds,
    };

    const res = await fetch(f.id ? `/api/v1/items/${f.id}` : "/api/v1/items", {
      method: f.id ? "PATCH" : "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify(payload),
    });
    setBusy(false);
    if (!res.ok) {
      const err = await res.json().catch(() => ({}));
      toast({ title: "Error", description: err.error ?? "Could not save.", variant: "destructive" });
      return;
    }
    toast({ title: f.id ? "Saved!" : "Item added!" });
    setOpen(false);
    router.refresh();
  }

  return (
    <>
      <span onClick={() => { setF(initial); setLabels(initialLabels); setOpen(true); }}>{trigger}</span>
      <Dialog open={open} onOpenChange={setOpen}>
        <DialogContent className="max-w-lg max-h-[90vh] overflow-y-auto">
          <DialogHeader><DialogTitle>{title}</DialogTitle></DialogHeader>
          <form onSubmit={submit} className="space-y-4">
            <div className="grid grid-cols-2 gap-3">
              <div className="col-span-2 space-y-1.5">
                <Label>Name *</Label>
                <Input value={f.name} onChange={(e) => set("name", e.target.value)} placeholder="Cordless drill" />
                {error && <p className="text-xs text-destructive">{error}</p>}
              </div>

              <div className="space-y-1.5">
                <Label>Quantity</Label>
                <Input type="number" min="0" step="any" value={f.quantity} onChange={(e) => set("quantity", e.target.value)} />
              </div>
              <div className="space-y-1.5">
                <Label>Unit</Label>
                <Input value={f.unit} onChange={(e) => set("unit", e.target.value)} placeholder="each" />
              </div>

              <div className="space-y-1.5">
                <Label>Location</Label>
                <Select value={f.locationId || NONE} onValueChange={(v) => set("locationId", v === NONE ? "" : v)}>
                  <SelectTrigger><SelectValue placeholder="—" /></SelectTrigger>
                  <SelectContent>
                    <SelectItem value={NONE}>—</SelectItem>
                    {locations.map((l) => <SelectItem key={l.id} value={l.id}>{l.name}</SelectItem>)}
                  </SelectContent>
                </Select>
              </div>
              <div className="space-y-1.5">
                <Label>Inside item</Label>
                <Select value={f.parentItemId || NONE} onValueChange={(v) => set("parentItemId", v === NONE ? "" : v)}>
                  <SelectTrigger><SelectValue placeholder="—" /></SelectTrigger>
                  <SelectContent>
                    <SelectItem value={NONE}>— (not inside another item)</SelectItem>
                    {parentOptions.map((i) => <SelectItem key={i.id} value={i.id}>{i.name}</SelectItem>)}
                  </SelectContent>
                </Select>
              </div>

              <div className="space-y-1.5">
                <Label>Brand</Label>
                <Input value={f.brand} onChange={(e) => set("brand", e.target.value)} placeholder="DeWalt" />
              </div>
              <div className="space-y-1.5">
                <Label>Model #</Label>
                <Input value={f.modelNumber} onChange={(e) => set("modelNumber", e.target.value)} />
              </div>
              <div className="space-y-1.5">
                <Label>Serial #</Label>
                <Input value={f.serial} onChange={(e) => set("serial", e.target.value)} />
              </div>
              <div className="space-y-1.5">
                <Label>Value ($)</Label>
                <Input type="number" min="0" step="0.01" value={f.value} onChange={(e) => set("value", e.target.value)} />
              </div>
              <div className="space-y-1.5">
                <Label>Purchased</Label>
                <Input type="date" value={f.purchaseDate} onChange={(e) => set("purchaseDate", e.target.value)} />
              </div>
              <div className="space-y-1.5">
                <Label>Warranty until</Label>
                <Input type="date" value={f.warrantyExpiry} onChange={(e) => set("warrantyExpiry", e.target.value)} disabled={f.lifetimeWarranty} />
              </div>

              <div className="col-span-2 space-y-1.5">
                <Label>Purchased from</Label>
                <Input value={f.purchaseFrom} onChange={(e) => set("purchaseFrom", e.target.value)} placeholder="Home Depot, Amazon, gift…" />
              </div>
              <div className="col-span-2 space-y-1.5">
                <Label>Warranty details</Label>
                <Textarea rows={2} value={f.warrantyDetails} onChange={(e) => set("warrantyDetails", e.target.value)} placeholder="Coverage, claim info…" />
              </div>
              <div className="col-span-2 flex flex-wrap gap-x-6 gap-y-2">
                <label className="flex items-center gap-2 text-sm cursor-pointer">
                  <input type="checkbox" checked={f.lifetimeWarranty} onChange={(e) => set("lifetimeWarranty", e.target.checked)} className="accent-[hsl(var(--leaf))]" />
                  Lifetime warranty
                </label>
                <label className="flex items-center gap-2 text-sm cursor-pointer">
                  <input type="checkbox" checked={f.insured} onChange={(e) => set("insured", e.target.checked)} className="accent-[hsl(var(--leaf))]" />
                  Insured
                </label>
              </div>

              <div className="col-span-2 space-y-1.5">
                <Label>Labels</Label>
                <div className="flex flex-wrap gap-1.5">
                  {labels.map((l) => (
                    <button key={l.id} type="button" onClick={() => toggleLabel(l.id)}>
                      <Badge variant={f.labelIds.includes(l.id) ? "default" : "outline"} className="cursor-pointer">
                        {l.name}
                      </Badge>
                    </button>
                  ))}
                </div>
                <div className="flex gap-2 mt-1">
                  <Input value={newLabel} onChange={(e) => setNewLabel(e.target.value)}
                    onKeyDown={(e) => { if (e.key === "Enter") { e.preventDefault(); addLabel(); } }}
                    placeholder="New label…" className="h-8 text-sm" />
                  <Button type="button" size="sm" variant="outline" onClick={addLabel}>Add</Button>
                </div>
              </div>

              <div className="col-span-2 space-y-1.5">
                <Label>Notes</Label>
                <Textarea rows={2} value={f.notes} onChange={(e) => set("notes", e.target.value)} />
              </div>
            </div>

            <DialogFooter>
              <Button type="button" variant="outline" onClick={() => setOpen(false)}>Cancel</Button>
              <Button type="submit" disabled={busy}>{busy ? "Saving…" : "Save"}</Button>
            </DialogFooter>
          </form>
        </DialogContent>
      </Dialog>
    </>
  );
}

export function AddItemButton(props: { locations: LocationOpt[]; items: ItemOpt[]; labels: LabelOpt[] }) {
  return (
    <ItemDialog title="Add an item" initial={blankItem()} {...props}
      trigger={<Button size="sm"><Plus className="h-4 w-4 mr-1" />Add item</Button>} />
  );
}

export function EditItemButton(props: { item: ItemFields; locations: LocationOpt[]; items: ItemOpt[]; labels: LabelOpt[] }) {
  const { item, ...rest } = props;
  return (
    <ItemDialog title="Edit item" initial={item} {...rest}
      trigger={<Button variant="outline" size="sm"><Pencil className="h-4 w-4 mr-1" />Edit</Button>} />
  );
}
