"use client";

import { useState } from "react";
import { useTranslations } from "next-intl";
import { toast } from "sonner";
import { Snowflake, Refrigerator, ChefHat, Check } from "lucide-react";
import { Button } from "@/components/ui/button";
import { useLocale } from "@/lib/i18n/provider";
import { stripMarkdown } from "@/lib/utils";
import { queueOfflineAction } from "@/lib/offline-queue";

type Dish = {
  id: string;
  name: string;
  description: string | null;
  fridgeDays: number;
  freezerFriendly: boolean;
  freezerNote: string | null;
  dayOfInstructions: string;
  cookedAt: string | null;
};

function expiresOn(cookedAt: string, fridgeDays: number): Date {
  const d = new Date(cookedAt);
  d.setDate(d.getDate() + fridgeDays);
  return d;
}

export function BatchCookDishes({ recipeId, dishes: initialDishes }: { recipeId: string; dishes: Dish[] }) {
  const t = useTranslations("recipe");
  const { locale } = useLocale();
  const [dishes, setDishes] = useState(initialDishes);
  const [markingId, setMarkingId] = useState<string | null>(null);

  async function markCooked(dishId: string) {
    setMarkingId(dishId);
    const body = { batchDishId: dishId, deductFromPantry: true };
    try {
      let res: Response;
      try {
        res = await fetch(`/api/v1/recipes/${recipeId}/cooked`, {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify(body),
        });
      } catch {
        // fetch() throwing (rather than resolving with a non-ok status)
        // means the network itself is unreachable — queue it for the
        // service worker (or the online-event fallback) to replay later,
        // rather than treating it as a real failure.
        await queueOfflineAction({
          method: "POST",
          url: `/api/v1/recipes/${recipeId}/cooked`,
          body,
          description: `Mark dish ${dishId} as cooked`,
        });
        const now = new Date().toISOString();
        setDishes((prev) => prev.map((d) => (d.id === dishId ? { ...d, cookedAt: now } : d)));
        toast.info(t("batchCookMarkQueuedOffline"));
        return;
      }
      if (!res.ok) {
        toast.error(t("batchCookMarkFailed"));
        return;
      }
      const now = new Date().toISOString();
      setDishes((prev) => prev.map((d) => (d.id === dishId ? { ...d, cookedAt: now } : d)));
      toast.success(t("batchCookMarkSuccess"));
    } finally {
      setMarkingId(null);
    }
  }

  return (
    <div className="space-y-4">
      <h2 className="text-xl font-semibold">{t("batchCookDishesTitle")}</h2>
      <div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
        {dishes.map((dish) => (
          <div key={dish.id} className="rounded-xl border p-4 space-y-3">
            <div>
              <h3 className="font-semibold">{dish.name}</h3>
              {dish.description && <p className="text-sm text-muted-foreground mt-0.5">{stripMarkdown(dish.description)}</p>}
            </div>

            <div className="flex flex-wrap gap-2 text-xs">
              <span className="inline-flex items-center gap-1 rounded-full bg-muted px-2.5 py-1">
                <Refrigerator className="h-3.5 w-3.5" />
                {t("batchCookFridgeDays", { days: dish.fridgeDays })}
              </span>
              {dish.freezerFriendly && (
                <span className="inline-flex items-center gap-1 rounded-full bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-200 px-2.5 py-1">
                  <Snowflake className="h-3.5 w-3.5" />
                  {t("batchCookFreezerFriendly")}
                </span>
              )}
            </div>
            {dish.freezerNote && (
              <p className="text-xs text-muted-foreground">{dish.freezerNote}</p>
            )}

            <div className="flex gap-2 rounded-lg bg-muted/50 p-3">
              <ChefHat className="h-4 w-4 text-primary shrink-0 mt-0.5" />
              <div>
                <p className="text-xs font-medium">{t("batchCookDayOf")}</p>
                <p className="text-sm text-muted-foreground mt-0.5">{stripMarkdown(dish.dayOfInstructions)}</p>
              </div>
            </div>

            {dish.cookedAt ? (
              <p className="text-xs text-muted-foreground flex items-center gap-1.5">
                <Check className="h-3.5 w-3.5 text-primary" />
                {t("batchCookExpiresOn", {
                  date: expiresOn(dish.cookedAt, dish.fridgeDays).toLocaleDateString(locale, { month: "short", day: "numeric" }),
                })}
              </p>
            ) : (
              <Button
                variant="outline"
                size="sm"
                className="w-full"
                disabled={markingId === dish.id}
                onClick={() => { void markCooked(dish.id); }}
              >
                <ChefHat className="h-3.5 w-3.5" />
                {t("batchCookMarkCooked")}
              </Button>
            )}
          </div>
        ))}
      </div>
    </div>
  );
}
