import { useEffect, useRef, useState } from "react";
import { useTranslation } from "react-i18next";
import { FileDown, Loader2 } from "lucide-react";
import { fetchRecipeById } from "@/api/recipes.api";
import { extractApiError } from "@/api/axiosInstance";
import {
  PDF_PAGE_STYLE,
  RecipePdfPage,
  ShoppingListPdfPage,
  buildShoppingList,
} from "@/components/pdf/pdfPageComponents";
import { generatePdf } from "@/utils/pdfExport";
import { useMealCategoryLabels } from "@/i18n/useMealCategoryLabel";
import type { RecipeDetail } from "@/types/recipe.types";

interface PdfGeneratorProps {
  selectedIds: number[];
  disabled?: boolean;
}

type Phase = "idle" | "loading" | "rendering";

export function PdfGenerator({ selectedIds, disabled }: PdfGeneratorProps) {
  const { t, i18n } = useTranslation();
  const categoryLabels = useMealCategoryLabels();
  const [phase, setPhase] = useState<Phase>("idle");
  const [recipes, setRecipes] = useState<RecipeDetail[]>([]);
  const [error, setError] = useState<string | null>(null);
  const renderAreaRef = useRef<HTMLDivElement | null>(null);

  async function handleGenerate() {
    if (selectedIds.length === 0 || phase !== "idle") return;
    setError(null);
    setPhase("loading");
    try {
      const details = await Promise.all(selectedIds.map((id) => fetchRecipeById(id)));
      setRecipes(details);
      setPhase("rendering");
    } catch (err) {
      setError(extractApiError(err, t("errors.pdfLoadFailed")));
      setPhase("idle");
    }
  }

  useEffect(() => {
    if (phase !== "rendering" || recipes.length === 0) return;

    let cancelled = false;
    const run = async () => {
      await document.fonts?.ready?.catch(() => undefined);
      await new Promise((r) => requestAnimationFrame(() => requestAnimationFrame(r)));
      if (cancelled) return;
      try {
        await generatePdf("dailymeals-plan.pdf");
      } catch (err) {
        setError(extractApiError(err, t("errors.pdfGenerateFailed")));
      } finally {
        if (!cancelled) {
          setPhase("idle");
          setRecipes([]);
        }
      }
    };
    void run();
    return () => {
      cancelled = true;
    };
  }, [phase, recipes, t]);

  const shoppingList = recipes.length > 0 ? buildShoppingList(recipes) : [];
  const generatedOn = new Date().toLocaleDateString(i18n.language, {
    year: "numeric",
    month: "long",
    day: "numeric",
  });

  return (
    <>
      <button
        type="button"
        onClick={() => void handleGenerate()}
        disabled={disabled || selectedIds.length === 0 || phase !== "idle"}
        className="btn-primary"
      >
        {phase !== "idle" ? (
          <Loader2 className="h-4 w-4 animate-spin" />
        ) : (
          <FileDown className="h-4 w-4" />
        )}
        {phase === "loading"
          ? t("pdf.preparing")
          : phase === "rendering"
            ? t("pdf.generating")
            : t("pdf.generate")}
      </button>

      {error && <p className="mt-2 text-sm text-red-600 dark:text-red-400">{error}</p>}

      {phase === "rendering" && (
        <div id="pdf-render-area" ref={renderAreaRef}>
          {recipes.map((recipe) => (
            <div className="pdf-page" style={PDF_PAGE_STYLE} key={recipe.id}>
              <RecipePdfPage recipe={recipe} categoryLabels={categoryLabels} t={t} />
            </div>
          ))}
          <div className="pdf-page" style={PDF_PAGE_STYLE}>
            <ShoppingListPdfPage
              items={shoppingList}
              recipes={recipes}
              generatedOn={generatedOn}
              categoryLabels={categoryLabels}
              t={t}
            />
          </div>
        </div>
      )}
    </>
  );
}
