"use client";

import { useState, useMemo, useRef } from "react";
import { PackageOpen } from "lucide-react";
import { Button } from "@/components/ui/button";
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter } from "@/components/ui/dialog";
import { Label } from "@/components/ui/label";
import { cn } from "@/lib/utils";
import { PANTRY_USE_REASONS, type PantryUseReason } from "@/lib/pantry/core";
import type { PantryItem } from "./pantry-client";

const QUICK_REASONS = ["Family dinner", "Dinner party", "Taking on a trip", "Meal prep", "Gave it away"];

type Pull = { amount: string };

export function PullDialog({ items, onSuccess }: { items: PantryItem[]; onSuccess: () => void }) {
  const [open, setOpen] = useState(false);
  const [search, setSearch] = useState("");
  const [pulls, setPulls] = useState<Record<string, Pull>>({});
  const [reason, setReason] = useState("");
  const [disposition, setDisposition] = useState<PantryUseReason>("consumed");
  const [selectedReason, setSelectedReason] = useState<string | null>(null);
  const [saving, setSaving] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const searchRef = useRef<HTMLInputElement>(null);

  const filtered = useMemo(() => {
    const q = search.trim().toLowerCase();
    if (!q) return items;
    return items.filter(i =>
      i.name.toLowerCase().includes(q) ||
      i.pantryCategory?.toLowerCase().includes(q) ||
      i.pantrySubcategory?.toLowerCase().includes(q) ||
      i.tags?.some(t => t.toLowerCase().includes(q))
    );
  }, [items, search]);

  const activePulls = Object.entries(pulls).filter(([, p]) => {
    const n = parseFloat(p.amount);
    return !isNaN(n) && n > 0;
  });

  function setAmount(id: string, val: string) {
    setPulls(prev => ({ ...prev, [id]: { amount: val } }));
  }

  function pickReason(r: string) {
    if (selectedReason === r) { setSelectedReason(null); setReason(""); }
    else { setSelectedReason(r); setReason(r); }
  }

  function reset() {
    setSearch("");
    setPulls({});
    setReason("");
    setDisposition("consumed");
    setSelectedReason(null);
    setError(null);
  }

  async function handleSubmit(e: React.FormEvent) {
    e.preventDefault();
    if (activePulls.length === 0) { setError("Enter a quantity for at least one item."); return; }

    // Validate amounts against stock
    for (const [id, p] of activePulls) {
      const item = items.find(i => i.id === id);
      const amt = parseFloat(p.amount);
      if (item && amt > item.quantity) {
        setError(`Only ${item.quantity} ${item.unit ?? ""} of "${item.name}" on hand.`.trim());
        return;
      }
    }

    setSaving(true);
    setError(null);
    try {
      const res = await fetch("/api/v1/pantry/bulk-use", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          pulls: activePulls.map(([id, p]) => ({ id, amount: parseFloat(p.amount) })),
          notes: reason.trim() || null,
          reason: disposition,
        }),
      });
      const data = await res.json();
      if (!res.ok) throw new Error(data.error ?? "Failed");
      if (data.skipped?.length > 0) {
        // Someone else deleted these since the list loaded — say so instead of
        // pretending the whole pull worked.
        const names = data.skipped.map(
          (s: { id: string }) => items.find(i => i.id === s.id)?.name ?? "an item",
        );
        setPulls({});
        setError(
          `Couldn't pull ${names.join(", ")} — no longer in the pantry. Everything else was pulled.`,
        );
        onSuccess();
        return;
      }
      setOpen(false);
      reset();
      onSuccess();
    } catch (err) {
      setError(String(err).replace("Error: ", ""));
    } finally {
      setSaving(false);
    }
  }

  const inputCls = "w-full rounded-md border bg-background px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-ring";

  return (
    <>
      <Button variant="outline" onClick={() => { reset(); setOpen(true); }} className="gap-2">
        <PackageOpen className="h-4 w-4" /> Pull from pantry
      </Button>

      <Dialog open={open} onOpenChange={o => { setOpen(o); if (!o) reset(); }}>
        <DialogContent className="max-w-lg max-h-[90vh] flex flex-col p-0">
          <DialogHeader className="px-6 pt-6 pb-0 shrink-0">
            <DialogTitle>Pull from pantry</DialogTitle>
          </DialogHeader>

          <form onSubmit={handleSubmit} className="flex flex-col flex-1 min-h-0">
            {/* Reason */}
            <div className="px-6 pt-4 pb-3 border-b space-y-2 shrink-0">
              <div className="flex flex-wrap gap-1.5">
                {PANTRY_USE_REASONS.map(r => (
                  <button key={r.value} type="button" onClick={() => setDisposition(r.value)}
                    className={cn("rounded-full border px-3 py-1 text-xs font-medium transition-colors",
                      disposition === r.value ? "bg-primary text-primary-foreground border-primary" : "bg-background hover:bg-accent"
                    )}>
                    {r.label}
                  </button>
                ))}
              </div>
              <Label className="text-xs text-muted-foreground">What's it for? (optional)</Label>
              <div className="flex flex-wrap gap-1.5">
                {QUICK_REASONS.map(r => (
                  <button key={r} type="button" onClick={() => pickReason(r)}
                    className={cn("rounded-full border px-3 py-1 text-xs",
                      selectedReason === r ? "bg-primary text-primary-foreground border-primary" : "bg-background hover:bg-accent"
                    )}>
                    {r}
                  </button>
                ))}
              </div>
              <input
                className={inputCls}
                placeholder="Or type your own reason…"
                value={reason}
                onChange={e => { setReason(e.target.value); setSelectedReason(null); }}
              />
            </div>

            {/* Search */}
            <div className="px-6 py-3 border-b shrink-0">
              <input
                ref={searchRef}
                className={inputCls}
                placeholder="Search by name, category, or tag…"
                value={search}
                onChange={e => setSearch(e.target.value)}
                autoFocus
              />
            </div>

            {/* Items list */}
            <div className="flex-1 overflow-y-auto px-6 py-2">
              {filtered.length === 0 && (
                <p className="text-sm text-muted-foreground text-center py-8">No items match.</p>
              )}
              {filtered.map(item => {
                const amt = pulls[item.id]?.amount ?? "";
                const n = parseFloat(amt);
                const active = !isNaN(n) && n > 0;
                const over = active && n > item.quantity;
                return (
                  <div key={item.id}
                    className={cn("flex items-center gap-3 py-2.5 border-b last:border-0",
                      active && "bg-primary/5 -mx-6 px-6 rounded"
                    )}>
                    <div className="flex-1 min-w-0">
                      <p className="text-sm font-medium truncate">{item.name}</p>
                      <p className="text-xs text-muted-foreground">
                        {item.quantity} {item.unit ?? "on hand"}
                        {item.pantryCategory && <> · {item.pantryCategory}</>}
                        {item.tags?.length > 0 && <> · {item.tags.join(", ")}</>}
                      </p>
                    </div>
                    <div className="shrink-0 w-24">
                      <input
                        type="number"
                        min="0"
                        step="1"
                        className={cn(
                          "w-full rounded-md border px-2 py-1.5 text-sm text-center focus:outline-none focus:ring-2 focus:ring-ring",
                          over && "border-destructive text-destructive",
                          active && !over && "border-primary"
                        )}
                        placeholder="0"
                        value={amt}
                        onChange={e => setAmount(item.id, e.target.value)}
                      />
                      {over && <p className="text-[10px] text-destructive text-center mt-0.5">Max {item.quantity}</p>}
                    </div>
                    <span className="text-xs text-muted-foreground shrink-0 w-8">{item.unit ?? ""}</span>
                  </div>
                );
              })}
            </div>

            {/* Footer */}
            <div className="px-6 py-4 border-t shrink-0 space-y-3">
              {activePulls.length > 0 && (
                <p className="text-xs text-muted-foreground">
                  Pulling {activePulls.length} item{activePulls.length !== 1 ? "s" : ""}
                  {reason && <> for <strong>{reason}</strong></>}
                </p>
              )}
              {error && <p className="text-sm text-destructive">{error}</p>}
              <div className="flex gap-2 justify-end">
                <Button type="button" variant="outline" onClick={() => setOpen(false)}>Cancel</Button>
                <Button type="submit" disabled={saving || activePulls.length === 0}>
                  {saving ? "Saving…" : activePulls.length > 0 ? `Pull ${activePulls.length} item${activePulls.length !== 1 ? "s" : ""}` : "Pull"}
                </Button>
              </div>
            </div>
          </form>
        </DialogContent>
      </Dialog>
    </>
  );
}
