import { useCallback, useEffect, useRef, useState } from 'react';

import useHuSnackbar from '@material-hu/components/design-system/Snackbar';

import { getPayrollReceiptPdf } from '../services';
import { type PayrollReceipt, type PdfCache } from '../types';
import { buildTitle, getReceiptKey, triggerDownload } from '../utils';

type PdfViewerState = { url: string; title: string };

export const useMobilityAdoPdfs = () => {
  const { enqueueSnackbar } = useHuSnackbar();
  const [loadingReceiptKey, setLoadingReceiptKey] = useState<string | null>(
    null,
  );
  const [pdfViewerState, setPdfViewerState] = useState<PdfViewerState | null>(
    null,
  );
  const pdfCacheRef = useRef<PdfCache | null>(null);

  useEffect(
    () => () => {
      if (pdfCacheRef.current?.url) {
        URL.revokeObjectURL(pdfCacheRef.current.url);
      }
    },
    [],
  );

  const fetchAndCachePdf = useCallback(
    async (receipt: PayrollReceipt): Promise<PdfCache | null> => {
      const key = getReceiptKey(receipt);
      const cached = pdfCacheRef.current;
      if (cached?.receiptKey === key) return cached;
      if (cached?.url) URL.revokeObjectURL(cached.url);
      // Drop the cache before the fetch so a failure cannot leave the ref pointing at a revoked URL.
      pdfCacheRef.current = null;
      setLoadingReceiptKey(key);
      try {
        const response = await getPayrollReceiptPdf(receipt);
        const url = URL.createObjectURL(response.data);
        const next: PdfCache = {
          receiptKey: key,
          url,
          title: buildTitle(receipt),
        };
        pdfCacheRef.current = next;
        return next;
      } catch (err) {
        console.error(err);
        enqueueSnackbar({
          title: 'No pudimos cargar el recibo. Intentá de nuevo.',
          variant: 'error',
        });
        return null;
      } finally {
        setLoadingReceiptKey(null);
      }
    },
    [enqueueSnackbar],
  );

  const handleReceiptClick = useCallback(
    async (receipt: PayrollReceipt) => {
      const cached = await fetchAndCachePdf(receipt);
      if (cached) setPdfViewerState({ url: cached.url, title: cached.title });
    },
    [fetchAndCachePdf],
  );

  const handleDownloadFromMenu = useCallback(
    async (receipt: PayrollReceipt) => {
      const cached = await fetchAndCachePdf(receipt);
      if (!cached) return;
      triggerDownload(cached.url, cached.title);
    },
    [fetchAndCachePdf],
  );

  const handleClosePdf = useCallback(() => {
    setPdfViewerState(null);
  }, []);

  return {
    pdfViewerState,
    loadingReceiptKey,
    handleReceiptClick,
    handleDownloadFromMenu,
    handleClosePdf,
  };
};
