"use client";

import { useState, useEffect } from "react";
import { useTranslations } from "next-intl";
import { ShoppingCart, Loader2, Plus, 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 { Label } from "@/components/ui/label";
import { Input } from "@/components/ui/input";
import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group";
import { Separator } from "@/components/ui/separator";

type Ingredient = {
  rawName: string;
  quantity?: string | number | null;
  unit?: string | null;
};

type ShoppingList = { id: string; name: string };

function scaleQty(quantity: string | number | null | undefined, scale: number): string | undefined {
  if (!quantity) return undefined;
  const n = typeof quantity === "number" ? quantity : parseFloat(quantity);
  if (isNaN(n)) return String(quantity);
  if (n === 0) return undefined;
  const scaled = n * scale;
  return scaled % 1 === 0 ? String(scaled) : scaled.toFixed(2).replace(/\.?0+$/, "");
}

export function AddToShoppingListButton({
  recipeId,
  recipeTitle,
  baseServings,
  ingredients,
}: {
  recipeId: string;
  recipeTitle: string;
  baseServings: number;
  ingredients: Ingredient[];
}) {
  const t = useTranslations("recipe");
  const tShopping = useTranslations("shoppingLists");
  const tCommon = useTranslations("common");
  const tForm = useTranslations("recipeForm");
  const [open, setOpen] = useState(false);
  const [lists, setLists] = useState<ShoppingList[]>([]);
  const [loadingLists, setLoadingLists] = useState(false);
  const [mode, setMode] = useState<"existing" | "new">("existing");
  const [selectedListId, setSelectedListId] = useState<string>("");
  const [newListName, setNewListName] = useState(`${recipeTitle} shopping`);
  const [servings, setServings] = useState(baseServings);
  const [adding, setAdding] = useState(false);

  useEffect(() => {
    if (!open) return;
    setLoadingLists(true);
    fetch("/api/v1/shopping-lists")
      .then((r) => r.json() as Promise<ShoppingList[]>)
      .then((data) => {
        setLists(data);
        if (data.length > 0) {
          setMode("existing");
          setSelectedListId(data[0]!.id);
        } else {
          setMode("new");
        }
      })
      .catch(() => setMode("new"))
      .finally(() => setLoadingLists(false));
  }, [open]);

  const scale = servings / baseServings;

  const items = ingredients.map((ing) => ({
    rawName: ing.rawName,
    quantity: scaleQty(ing.quantity, scale),
    unit: ing.unit ?? undefined,
  }));

  async function handleAdd() {
    setAdding(true);
    try {
      let listId = selectedListId;

      if (mode === "new") {
        const res = await fetch("/api/v1/shopping-lists", {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({ name: newListName.trim() || recipeTitle }),
        });
        if (!res.ok) { toast.error(t("shoppingListCreateFailed")); return; }
        const created = await res.json() as { id: string };
        listId = created.id;
      }

      const res = await fetch(`/api/v1/shopping-lists/${listId}/items`, {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ items }),
      });

      if (!res.ok) { toast.error(t("shoppingListAddFailed")); return; }

      toast.success(tShopping("addedCount", { count: items.length }));
      setOpen(false);
    } finally {
      setAdding(false);
    }
  }

  return (
    <>
      <TooltipProvider>
        <Tooltip>
          <TooltipTrigger render={
            <Button variant="ghost" size="icon" onClick={() => setOpen(true)} aria-label={tShopping("addToList")}>
              <ShoppingCart className="h-4 w-4" />
            </Button>
          } />
          <TooltipContent>{tShopping("addToList")}</TooltipContent>
        </Tooltip>
      </TooltipProvider>

      <Dialog open={open} onOpenChange={setOpen}>
        <DialogContent className="max-w-lg">
          <DialogHeader>
            <DialogTitle className="flex items-center gap-2">
              <ShoppingCart className="h-5 w-5 text-primary" />
              {tShopping("dialogTitle")}
            </DialogTitle>
            <DialogDescription>
              {tShopping.rich("dialogDescription", {
                title: recipeTitle,
                strong: (chunks) => <strong>{chunks}</strong>,
              })}
            </DialogDescription>
          </DialogHeader>

          <div className="space-y-4">
            {/* Servings scaler */}
            <div className="flex items-center gap-3">
              <Label className="shrink-0">{tForm("servings")}</Label>
              <div className="flex items-center gap-2">
                <Button
                  type="button" variant="ghost" size="icon" className="h-7 w-7"
                  onClick={() => setServings((s) => Math.max(1, s - 1))}
                  disabled={servings <= 1}
                  aria-label={tCommon("decrease")}
                >−</Button>
                <span className="w-8 text-center font-medium">{servings}</span>
                <Button
                  type="button" variant="ghost" size="icon" className="h-7 w-7"
                  onClick={() => setServings((s) => s + 1)}
                  aria-label={tCommon("increase")}
                >+</Button>
              </div>
              {scale !== 1 && (
                <span className="text-xs text-muted-foreground">({scale > 1 ? "×" : "÷"}{Math.abs(scale) !== 1 ? (scale > 1 ? scale.toFixed(2).replace(/\.?0+$/, "") : (1 / scale).toFixed(2).replace(/\.?0+$/, "")) : ""}  {tShopping("scaledSuffix")}</span>
              )}
            </div>

            <Separator />

            {/* List picker */}
            {loadingLists ? (
              <div className="flex items-center gap-2 text-sm text-muted-foreground py-2">
                <Loader2 className="h-4 w-4 animate-spin" /> {tShopping("loadingLists")}
              </div>
            ) : (
              <div className="space-y-3">
                {lists.length > 0 && (
                  <RadioGroup value={mode} onValueChange={(v: string) => setMode(v as "existing" | "new")}>
                    <div className="flex items-center gap-2">
                      <RadioGroupItem value="existing" id="mode-existing" />
                      <Label htmlFor="mode-existing">{tShopping("modeExisting")}</Label>
                    </div>
                    {mode === "existing" && (
                      <div className="ml-6 space-y-1.5">
                        {lists.map((list) => (
                          <button
                            key={list.id}
                            onClick={() => setSelectedListId(list.id)}
                            className={`w-full text-left px-3 py-2 rounded-md text-sm transition-colors flex items-center justify-between ${
                              selectedListId === list.id
                                ? "bg-primary text-primary-foreground"
                                : "bg-muted hover:bg-accent"
                            }`}
                          >
                            {list.name}
                            {selectedListId === list.id && <Check className="h-3.5 w-3.5" />}
                          </button>
                        ))}
                      </div>
                    )}
                    <div className="flex items-center gap-2">
                      <RadioGroupItem value="new" id="mode-new" />
                      <Label htmlFor="mode-new">{tShopping("modeNew")}</Label>
                    </div>
                  </RadioGroup>
                )}

                {(mode === "new" || lists.length === 0) && (
                  <div className="space-y-1.5 ml-6">
                    <Input
                      value={newListName}
                      onChange={(e) => setNewListName(e.target.value)}
                      placeholder={tShopping("listNamePlaceholder")}
                    />
                  </div>
                )}
              </div>
            )}

            <Separator />

            <p className="text-xs text-muted-foreground">{tShopping("ingredientsWillBeAdded", { count: items.length })}</p>

            <div className="flex gap-2 justify-end">
              <Button variant="ghost" onClick={() => setOpen(false)} disabled={adding}>{tCommon("cancel")}</Button>
              <Button onClick={handleAdd} disabled={adding || loadingLists || (mode === "existing" && !selectedListId)}>
                {adding ? <Loader2 className="h-4 w-4 animate-spin" /> : <Plus className="h-4 w-4" />}
                {adding ? tShopping("adding") : tShopping("addIngredients")}
              </Button>
            </div>
          </div>
        </DialogContent>
      </Dialog>
    </>
  );
}
