"use client";

import { createContext, useContext, useEffect, useState, useCallback, useRef, ReactNode } from "react";
import { getMailInboxStats, type MailInboxStats } from "@/src/lib/api/mail-config";
import { tokenStorage } from "@/src/lib/api/storage";

const BASE = process.env.NEXT_PUBLIC_API_BASE_URL ?? "";

type MailBadgeContextValue = {
  stats: MailInboxStats | null;
  refresh: () => void;
};

const MailBadgeContext = createContext<MailBadgeContextValue>({ stats: null, refresh: () => {} });

export function MailBadgeProvider({ children }: { children: ReactNode }) {
  const [stats, setStats] = useState<MailInboxStats | null>(null);
  const esRef = useRef<EventSource | null>(null);
  const fallbackRef = useRef<ReturnType<typeof setInterval> | null>(null);

  const refresh = useCallback(async () => {
    try {
      setStats(await getMailInboxStats());
    } catch { /* silencieux */ }
  }, []);

  const connectSSE = useCallback(() => {
    // Ferme l'ancienne connexion si elle existe
    if (esRef.current) { esRef.current.close(); esRef.current = null; }

    const token = tokenStorage.getAccess();
    if (!token || !BASE) return;

    // Construit l'URL SSE avec le token en query param
    const base = BASE.replace(/\/+$/, "");
    const url = `${base}/tenant/mail/stream/?token=${encodeURIComponent(token)}`;

    const es = new EventSource(url);
    esRef.current = es;

    es.onmessage = (e) => {
      try {
        const data = JSON.parse(e.data) as { type: string; pending: number };
        if (data.type === "update") {
          setStats((prev) => prev
            ? { ...prev, pending: data.pending }
            : { pending: data.pending, dispatched: 0, processed: 0, rejected: 0 }
          );
          // Notifie la page inbox pour qu'elle recharge la liste
          window.dispatchEvent(new CustomEvent("mail:update", { detail: data }));
        }
      } catch { /* ignore */ }
    };

    es.onerror = () => {
      // EventSource reconnecte automatiquement, mais si le token a expiré
      // on bascule sur le polling de secours
      es.close();
      esRef.current = null;
      startFallbackPolling();
    };
  }, []);

  const startFallbackPolling = useCallback(() => {
    if (fallbackRef.current) return; // déjà en cours
    refresh();
    fallbackRef.current = setInterval(refresh, 30_000);
  }, [refresh]);

  useEffect(() => {
    // Chargement initial
    refresh();

    // Connexion SSE principale
    connectSSE();

    // Rafraîchissement immédiat quand l'onglet redevient visible (machine déverrouillée, etc.)
    const onVisible = () => {
      if (!document.hidden) {
        // Reconnecte SSE si fermé + refresh immédiat
        if (!esRef.current || esRef.current.readyState === EventSource.CLOSED) {
          connectSSE();
        }
        refresh();
      }
    };
    document.addEventListener("visibilitychange", onVisible);

    return () => {
      esRef.current?.close();
      esRef.current = null;
      if (fallbackRef.current) clearInterval(fallbackRef.current);
      document.removeEventListener("visibilitychange", onVisible);
    };
  }, [connectSSE, refresh]);

  return (
    <MailBadgeContext.Provider value={{ stats, refresh }}>
      {children}
    </MailBadgeContext.Provider>
  );
}

export function useMailBadge() {
  return useContext(MailBadgeContext);
}
