"use client";

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

const BASE_URL = String(
  process.env.NEXT_PUBLIC_PUBLIC_CATALOG_BASE_URL || "https://ktalogu.com.br"
).replace(/\/$/, "");

const INTERVALO_MS = 15000;

type LinhaRpc = Record<string, unknown>;

function mapear(linhas: LinhaRpc[]): LojaDaGalera[] {
  return linhas
    .filter((l) => String(l.slug || "").trim())
    .map((l, i) => ({
      posicao: i + 1,
      slug: String(l.slug),
      nome: String(l.nome || "Loja"),
      cidade: (l.cidade as string) || null,
      uf: (l.uf as string) || null,
      logo: (l.logo as string) || null,
      cor: (l.cor as string) || "#4425A7",
      slogan: (l.slogan as string) || null,
      produtos: Number(l.produtos) || 0,
      visitantes: Number(l.visitantes) || 0,
      visitas: Number(l.visitas) || 0,
      visitas30d: Number(l.visitas_30d) || 0,
      produtoViews: Number(l.produto_views) || 0,
      carrinhos: Number(l.carrinhos) || 0,
      pedidos: Number(l.pedidos) || 0,
      pedidos30d: Number(l.pedidos_30d) || 0,
      score: Number(l.score) || 0,
      url: `${BASE_URL}/${String(l.slug)}`,
    }));
}

/**
 * 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;

        const novas = mapear(dados.lojas || []);
        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 };
}
