"use client";

import { useEffect, useRef, useState } from "react";
import type { LojaDaGalera, Totais } from "./tipos";

const INTERVALO_MS = 15000;

/**
 * Mantem ranking e totais vivos sem recarregar a pagina.
 *
 * Alem do intervalo, refaz a busca quando a aba volta ao foco: e o caso real
 * de quem registra um pagamento no admin e volta para ca — sem isso ficaria
 * esperando o proximo ciclo para ver o proprio lancamento.
 *
 * Guarda a posicao anterior de cada loja para a lista conseguir mostrar quem
 * subiu ou caiu desde a ultima atualizacao.
 */
export function useGaleraAoVivo(inicial: { lojas: LojaDaGalera[]; totais: Totais }) {
  const [lojas, setLojas] = useState(inicial.lojas);
  const [totais, setTotais] = useState(inicial.totais);
  const [atualizadoEm, setAtualizadoEm] = useState<number | null>(null);
  const [posicoesAnteriores, setPosicoesAnteriores] = useState<Record<string, number>>({});

  /* O ciclo de busca precisa da lista atual para calcular quem subiu ou caiu,
     mas nao pode depender dela — recriar o intervalo a cada atualizacao faria
     o relogio reiniciar sem parar. O ref carrega o valor, sincronizado depois
     do render (escrever durante o render quebra o modelo do React). */
  const lojasRef = useRef(inicial.lojas);
  useEffect(() => {
    lojasRef.current = lojas;
  }, [lojas]);

  useEffect(() => {
    let ativo = true;

    const buscar = async () => {
      try {
        const resposta = await fetch("/api/lojas/ao-vivo", { cache: "no-store" });
        const dados = await resposta.json();
        if (!ativo || !dados?.ok) return;

        /* O servidor já manda as lojas prontas (galera-do-servidor.ts). */
        const novas = Array.isArray(dados.lojas) ? (dados.lojas as LojaDaGalera[]) : [];
        if (novas.length) {
          const antes: Record<string, number> = {};
          lojasRef.current.forEach((l) => {
            antes[l.slug] = l.posicao;
          });
          setPosicoesAnteriores(antes);
          setLojas(novas);
        }
        if (dados.totais) setTotais(dados.totais as Totais);
        setAtualizadoEm(Date.now());
      } catch {
        /* rede instavel mantem o ultimo estado bom na tela */
      }
    };

    const id = window.setInterval(buscar, INTERVALO_MS);
    const aoVoltar = () => {
      if (document.visibilityState === "visible") buscar();
    };
    document.addEventListener("visibilitychange", aoVoltar);
    window.addEventListener("focus", buscar);

    return () => {
      ativo = false;
      window.clearInterval(id);
      document.removeEventListener("visibilitychange", aoVoltar);
      window.removeEventListener("focus", buscar);
    };
  }, []);

  return { lojas, totais, atualizadoEm, posicoesAnteriores };
}
