"use client";

import { useState } from "react";
import { useTranslations } from "next-intl";
import { useRouter } from "next/navigation";
import { FakeProgressBar } from "@/components/ui/fake-progress-bar";
import { UtensilsCrossed, Sparkles, Loader2, ChefHat, Salad, Wine, Cake, Sandwich, Soup, Check } from "lucide-react";
import { toast } from "sonner";
import { Button } from "@/components/ui/button";
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip";
import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
  DialogDescription,
} from "@/components/ui/dialog";
import { Badge } from "@/components/ui/badge";
import { Separator } from "@/components/ui/separator";
import { cn } from "@/lib/utils";

type Pairing = {
  name: string;
  role: "starter" | "side" | "salad" | "bread" | "drink" | "dessert" | "sauce";
  description: string;
  whyItPairs: string;
  difficulty: "easy" | "medium" | "hard";
  prepTimeMins?: number;
};

const ROLE_ICON: Record<Pairing["role"], React.ElementType> = {
  starter: Soup,
  side: ChefHat,
  salad: Salad,
  bread: Sandwich,
  drink: Wine,
  dessert: Cake,
  sauce: ChefHat,
};

const ROLE_LABEL: Record<Pairing["role"], string> = {
  starter: "Starter",
  side: "Side",
  salad: "Salad",
  bread: "Bread",
  drink: "Drink",
  dessert: "Dessert",
  sauce: "Sauce",
};

const DIFFICULTY_VARIANT = {
  easy: "default",
  medium: "secondary",
  hard: "destructive",
} as const;

export function MealPairingButton({ recipeId }: { recipeId: string }) {
  const t = useTranslations("recipe");
  const router = useRouter();
  const [open, setOpen] = useState(false);
  const [loading, setLoading] = useState(false);
  const [selected, setSelected] = useState<Set<number>>(new Set());
  const [generatingProgress, setGeneratingProgress] = useState<{ current: number; total: number } | null>(null);
  const [pairings, setPairings] = useState<Pairing[]>([]);

  async function suggest() {
    setLoading(true);
    setPairings([]);
    setSelected(new Set());
    try {
      const res = await fetch(`/api/v1/ai/pairings/${recipeId}`, {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ count: 4 }),
      });
      if (!res.ok) { toast.error(t("pairingMealFailed")); return; }
      const data = await res.json() as { pairings: Pairing[] };
      setPairings(data.pairings);
    } finally {
      setLoading(false);
    }
  }

  function toggleSelect(i: number) {
    setSelected((prev) => {
      const next = new Set(prev);
      next.has(i) ? next.delete(i) : next.add(i);
      return next;
    });
  }

  async function generateSelected() {
    const indices = Array.from(selected).sort();
    setGeneratingProgress({ current: 0, total: indices.length });
    const savedIds: string[] = [];

    for (let n = 0; n < indices.length; n++) {
      const pairing = pairings[indices[n]!]!;
      setGeneratingProgress({ current: n + 1, total: indices.length });
      try {
        const genRes = await fetch("/api/v1/ai/generate", {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({ prompt: pairing.name }),
        });
        if (!genRes.ok) { toast.error(t("pairingGenerateFailed", { name: pairing.name })); continue; }
        const generated = await genRes.json() as {
          title: string; description?: string; baseServings?: number; prepMins?: number;
          cookMins?: number; difficulty?: string; dietaryTags?: Record<string, boolean>;
          ingredients: Array<{ rawName: string; quantity?: string; unit?: string; note?: string }>;
          steps: Array<{ instruction: string; timerSeconds?: number }>;
        };
        const saveRes = await fetch("/api/v1/recipes", {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({ ...generated, visibility: "private", aiGenerated: true }),
        });
        if (!saveRes.ok) { toast.error(t("pairingSaveFailed", { name: pairing.name })); continue; }
        const saved = await saveRes.json() as { id: string };
        savedIds.push(saved.id);
      } catch {
        toast.error(t("pairingGenerateFailed", { name: pairing.name }));
      }
    }

    setGeneratingProgress(null);
    setSelected(new Set());
    setOpen(false);

    if (savedIds.length === 1) {
      toast.success(t("pairingSuccess"));
      router.push(`/recipes/${savedIds[0]}/edit`);
    } else if (savedIds.length > 1) {
      toast.success(t("pairingBulkSuccess", { count: savedIds.length }));
      router.push("/recipes");
    }
  }

  return (
    <>
      <TooltipProvider>
        <Tooltip>
          <TooltipTrigger render={
            <Button variant="ghost" size="icon" onClick={() => { setOpen(true); if (pairings.length === 0) suggest(); }}>
              <UtensilsCrossed className="h-4 w-4" />
            </Button>
          } />
          <TooltipContent>Pair meal</TooltipContent>
        </Tooltip>
      </TooltipProvider>

      <Dialog open={open} onOpenChange={setOpen}>
        <DialogContent className="max-w-5xl max-h-[80vh] overflow-y-auto">
          <DialogHeader>
            <DialogTitle className="flex items-center gap-2">
              <UtensilsCrossed className="h-5 w-5 text-primary" />
              Complete the meal
            </DialogTitle>
            <DialogDescription>
              AI-suggested dishes that pair well with this recipe. Generate any of them as a new recipe.
            </DialogDescription>
          </DialogHeader>

          {loading ? (
            <div className="py-6 space-y-3">
              <FakeProgressBar active={loading} durationMs={8000} label="Finding perfect pairings…" />
            </div>
          ) : pairings.length === 0 ? (
            <div className="flex flex-col items-center gap-4 py-8">
              <Button onClick={suggest} size="lg">
                <Sparkles className="h-4 w-4" />
                Suggest pairings
              </Button>
            </div>
          ) : (
            <div className="space-y-3">
              {pairings.map((pairing, i) => {
                const Icon = ROLE_ICON[pairing.role];
                const isSelected = selected.has(i);
                return (
                  <div
                    key={i}
                    onClick={() => !generatingProgress && toggleSelect(i)}
                    className={cn(
                      "rounded-lg border p-4 cursor-pointer transition-colors",
                      isSelected ? "border-primary bg-primary/5" : "hover:border-muted-foreground/40"
                    )}
                  >
                    <div className="flex items-start gap-3">
                      <div className={cn(
                        "mt-0.5 shrink-0 h-5 w-5 rounded border-2 flex items-center justify-center transition-colors",
                        isSelected ? "border-primary bg-primary" : "border-muted-foreground/40"
                      )}>
                        {isSelected && <Check className="h-3 w-3 text-primary-foreground" strokeWidth={3} />}
                      </div>
                      <div className="mt-0.5 shrink-0 h-8 w-8 rounded-full bg-muted flex items-center justify-center">
                        <Icon className="h-4 w-4 text-muted-foreground" />
                      </div>
                      <div className="flex-1 min-w-0 space-y-1.5">
                        <div className="flex items-center gap-2 flex-wrap">
                          <span className="font-semibold">{pairing.name}</span>
                          <Badge variant="outline" className="text-xs">{ROLE_LABEL[pairing.role]}</Badge>
                          <Badge variant={DIFFICULTY_VARIANT[pairing.difficulty]} className="text-xs">{pairing.difficulty}</Badge>
                          {pairing.prepTimeMins && (
                            <span className="text-xs text-muted-foreground">{pairing.prepTimeMins}m</span>
                          )}
                        </div>
                        <p className="text-sm text-muted-foreground">{pairing.description}</p>
                        <p className="text-xs text-muted-foreground italic">&ldquo;{pairing.whyItPairs}&rdquo;</p>
                      </div>
                    </div>
                    {i < pairings.length - 1 && <Separator className="mt-3 -mx-4 w-[calc(100%+2rem)]" />}
                  </div>
                );
              })}

              {generatingProgress && (
                <FakeProgressBar
                  active={!!generatingProgress}
                  durationMs={generatingProgress.total * 10000}
                  label={`Generating recipe ${generatingProgress.current} of ${generatingProgress.total}…`}
                />
              )}
              <div className="flex gap-2 pt-1">
                <Button
                  variant="outline"
                  className="flex-1"
                  onClick={(e) => { e.stopPropagation(); suggest(); }}
                  disabled={!!generatingProgress}
                >
                  <Sparkles className="h-4 w-4" />
                  Regenerate
                </Button>
                <Button
                  className="flex-1"
                  onClick={(e) => { e.stopPropagation(); generateSelected(); }}
                  disabled={selected.size === 0 || !!generatingProgress}
                >
                  {generatingProgress ? (
                    <>
                      <Loader2 className="h-4 w-4 animate-spin" />
                      Generating {generatingProgress.current}/{generatingProgress.total}…
                    </>
                  ) : (
                    <>
                      <Sparkles className="h-4 w-4" />
                      Generate{selected.size > 0 ? ` (${selected.size})` : ""}
                    </>
                  )}
                </Button>
              </div>
            </div>
          )}
        </DialogContent>
      </Dialog>
    </>
  );
}
