"use client";

import { cloneElement, isValidElement, useState, type ReactElement } from "react";
import { useTranslations } from "next-intl";
import { toast } from "sonner";
import { ChefHat } from "lucide-react";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogHeader,
  DialogTitle,
} from "@/components/ui/dialog";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Switch } from "@/components/ui/switch";

function todayIso(): string {
  return new Date().toISOString().slice(0, 10);
}

interface MarkCookedDialogProps {
  recipeId: string;
  baseServings: number;
  batchDishId?: string;
  trigger: React.ReactNode;
  onLogged?: (log: { id: string; cookedAt: string; servings: number }) => void;
}

/** Logs a cook event — date, servings, and whether to deduct matching
 * ingredients from the pantry (default on). A recipe can be logged as
 * cooked any number of times; each submission is a new row, never an
 * update. */
export function MarkCookedDialog({ recipeId, baseServings, batchDishId, trigger, onLogged }: MarkCookedDialogProps) {
  const t = useTranslations("recipe");
  const tCommon = useTranslations("common");
  const [open, setOpen] = useState(false);
  const [date, setDate] = useState(todayIso());
  const [servings, setServings] = useState(baseServings);
  const [deductFromPantry, setDeductFromPantry] = useState(true);
  const [submitting, setSubmitting] = useState(false);

  async function handleSubmit() {
    setSubmitting(true);
    try {
      const res = await fetch(`/api/v1/recipes/${recipeId}/cooked`, {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          servings,
          cookedAt: date,
          deductFromPantry,
          ...(batchDishId ? { batchDishId } : {}),
        }),
      });
      if (!res.ok) throw new Error();
      const { id } = await res.json() as { id: string };
      toast.success(t("markCookedSuccess"));
      setOpen(false);
      onLogged?.({ id, cookedAt: date, servings });
    } catch {
      toast.error(t("markCookedFailed"));
    } finally {
      setSubmitting(false);
    }
  }

  const triggerElement = isValidElement(trigger)
    ? cloneElement(trigger as ReactElement<{ onClick?: () => void }>, { onClick: () => setOpen(true) })
    : trigger;

  return (
    <>
      {triggerElement}
      <Dialog open={open} onOpenChange={setOpen}>
        <DialogContent className="max-w-sm">
          <DialogHeader>
            <DialogTitle className="flex items-center gap-2">
              <ChefHat className="h-5 w-5 text-primary" />
              {t("markCookedTitle")}
            </DialogTitle>
            <DialogDescription>{t("markCookedDescription")}</DialogDescription>
          </DialogHeader>
          <div className="space-y-4">
            <div className="space-y-2">
              <Label htmlFor="mark-cooked-date">{t("markCookedDateLabel")}</Label>
              <Input id="mark-cooked-date" type="date" value={date} max={todayIso()} onChange={(e) => setDate(e.target.value || todayIso())} />
            </div>
            <div className="space-y-2">
              <Label htmlFor="mark-cooked-servings">{t("markCookedServingsLabel")}</Label>
              <Input
                id="mark-cooked-servings"
                type="number"
                min={1}
                value={servings}
                onChange={(e) => setServings(Math.max(1, Number(e.target.value) || baseServings))}
              />
            </div>
            <div className="flex items-center justify-between gap-3 rounded-lg border p-3">
              <div>
                <Label htmlFor="mark-cooked-deduct">{t("markCookedDeductLabel")}</Label>
                <p className="text-xs text-muted-foreground">{t("markCookedDeductDescription")}</p>
              </div>
              <Switch id="mark-cooked-deduct" checked={deductFromPantry} onCheckedChange={setDeductFromPantry} />
            </div>
            <div className="flex justify-end gap-2">
              <Button type="button" variant="outline" onClick={() => setOpen(false)} disabled={submitting}>
                {tCommon("cancel")}
              </Button>
              <Button type="button" onClick={() => { void handleSubmit(); }} disabled={submitting}>
                {submitting ? t("markCookedSaving") : t("markCookedSubmit")}
              </Button>
            </div>
          </div>
        </DialogContent>
      </Dialog>
    </>
  );
}
