import { useCallback, useEffect, useRef, useState } from "react";
import apiFetch from "../utils/api";
import { useAlert } from "../context/AlertContext";

/**
 * Shared "Zobrazit PDF" handlers for the document pages (offers, issued
 * orders) — both call their GET `…/:id/file` endpoint (archived NAS PDF with
 * live-render fallback). Hardened flow extracted from OfferDetail:
 * - pre-opens the tab synchronously (popup blockers only allow it inside the
 *   click's call stack), then streams the blob URL into it;
 * - double-click guard via a ref (state updates are async, a ref is not);
 * - 401 → silently close the tab (apiFetch already flagged the dead session);
 * - blob URLs are revoked after 60 s; pending revoke timeouts are cleared on
 *   unmount so they can't fire into a dead page.
 */

/**
 * List variant — ONE hook instance serves every row. `openPdf(id, url)`
 * fetches that row's PDF; `pdfLoadingId` reports which row is in flight (use
 * it for the per-row spinner + disabled state).
 */
export function useDocumentListPdf() {
  const alert = useAlert();
  const [pdfLoadingId, setPdfLoadingId] = useState<number | null>(null);
  const loadingRef = useRef(false);
  const blobTimeoutsRef = useRef<ReturnType<typeof setTimeout>[]>([]);

  useEffect(() => {
    // The array object is stable (we only push to it, never reassign), so
    // capturing it here keeps the cleanup in sync with the ref's content.
    const timeouts = blobTimeoutsRef.current;
    return () => {
      timeouts.forEach(clearTimeout);
    };
  }, []);

  const openPdf = useCallback(
    async (id: number, url: string) => {
      if (loadingRef.current) return;
      const newWindow = window.open("", "_blank");
      loadingRef.current = true;
      setPdfLoadingId(id);
      try {
        const response = await apiFetch(url);
        if (response.status === 401) {
          newWindow?.close();
          return;
        }
        if (!response.ok) {
          newWindow?.close();
          alert.error("Nepodařilo se vygenerovat PDF");
          return;
        }
        const blob = await response.blob();
        const blobUrl = URL.createObjectURL(blob);
        if (newWindow) newWindow.location.href = blobUrl;
        const timeoutId = setTimeout(() => URL.revokeObjectURL(blobUrl), 60000);
        blobTimeoutsRef.current.push(timeoutId);
      } catch {
        newWindow?.close();
        alert.error("Chyba připojení");
      } finally {
        loadingRef.current = false;
        setPdfLoadingId(null);
      }
    },
    [alert],
  );

  return { openPdf, pdfLoadingId };
}

/**
 * Detail variant — a single fixed URL, `openPdf()` takes no arguments.
 * Implemented on top of the list variant so the hardened flow lives once.
 */
export function useDocumentPdf(url: string | null) {
  const { openPdf: openListPdf, pdfLoadingId } = useDocumentListPdf();

  const openPdf = useCallback(async () => {
    if (!url) return;
    await openListPdf(0, url);
  }, [url, openListPdf]);

  return { openPdf, pdfLoading: pdfLoadingId !== null };
}
