"use client";

import { useEffect, useRef, useState } from "react";
import type { TotaisPublicos } from "../data/totais";
import { gsap, useGSAP } from "../gsap";

/*
  O número, no único bloco escuro da página: quanto dinheiro já passou pelo
  caixa das lojas que usam a Ktalogu. Número de verdade, vindo de pagamentos
  registrados; conta do zero ao entrar na tela e depois acompanha o banco
  enquanto a pessoa lê.
*/

const INTERVALO_MS = 15000;
const MOEDA = new Intl.NumberFormat("pt-BR", { style: "currency", currency: "BRL", minimumFractionDigits: 2, maximumFractionDigits: 2 });

function partirMoeda(valor: number) {
  const texto = MOEDA.format(valor);
  const corte = texto.lastIndexOf(",");
  if (corte < 0) return { inteiro: texto, centavos: "" };
  return { inteiro: texto.slice(0, corte), centavos: texto.slice(corte) };
}

function useTotaisAoVivo(inicial: TotaisPublicos) {
  const [totais, setTotais] = useState(inicial);
  const comecouSemNumero = useRef(!(inicial.negociado > 0));
  useEffect(() => {
    let ativo = true;
    const buscar = async () => {
      try {
        const resposta = await fetch("/api/totais-publicos", { cache: "no-store" });
        const dados = await resposta.json();
        if (!ativo || !dados?.ok || !dados.totais) return;
        const novos = dados.totais as TotaisPublicos;
        /* O dinheiro que passou pelo caixa só cresce: um zero aqui é falha,
           nunca o número de verdade. */
        setTotais((atual) => (novos.negociado > 0 || atual.negociado === 0 ? novos : atual));
      } catch {
        /* Rede instável mantém o último valor bom na tela. */
      }
    };
    /* A página chegou sem o número (o banco não respondeu no build): busca
       já, em vez de deixar o zero na tela até o primeiro ciclo. */
    if (comecouSemNumero.current) buscar();
    const id = window.setInterval(buscar, INTERVALO_MS);
    const aoVoltar = () => {
      if (document.visibilityState === "visible") buscar();
    };
    document.addEventListener("visibilitychange", aoVoltar);
    return () => {
      ativo = false;
      window.clearInterval(id);
      document.removeEventListener("visibilitychange", aoVoltar);
    };
  }, []);
  return totais;
}

export default function Numeros({ inicial }: { inicial: TotaisPublicos }) {
  const totais = useTotaisAoVivo(inicial);
  const raiz = useRef<HTMLElement | null>(null);
  const numero = useRef<HTMLSpanElement | null>(null);
  const centavos = useRef<HTMLElement | null>(null);
  const mostrado = useRef({ n: 0 });
  const ancorado = useRef(false);

  useGSAP(
    () => {
      const escrever = () => {
        const { inteiro, centavos: cents } = partirMoeda(mostrado.current.n);
        if (numero.current) numero.current.textContent = inteiro;
        if (centavos.current) centavos.current.textContent = cents;
      };
      const mm = gsap.matchMedia();
      mm.add("(prefers-reduced-motion: no-preference)", () => {
        gsap.to(mostrado.current, {
          n: totais.negociado,
          duration: 2.2,
          ease: "power3.out",
          onUpdate: escrever,
          onComplete: () => {
            ancorado.current = true;
          },
          scrollTrigger: { trigger: raiz.current, start: "top 75%", once: true },
        });
      });
      mm.add("(prefers-reduced-motion: reduce)", () => {
        mostrado.current.n = totais.negociado;
        ancorado.current = true;
        escrever();
      });
      return () => mm.revert();
    },
    { scope: raiz }
  );

  useGSAP(
    () => {
      if (!ancorado.current) return;
      gsap.to(mostrado.current, {
        n: totais.negociado,
        duration: 0.9,
        ease: "power2.out",
        onUpdate: () => {
          const { inteiro, centavos: cents } = partirMoeda(mostrado.current.n);
          if (numero.current) numero.current.textContent = inteiro;
          if (centavos.current) centavos.current.textContent = cents;
        },
      });
    },
    { dependencies: [totais.negociado], scope: raiz }
  );

  const inicialFormatado = partirMoeda(inicial.negociado);

  return (
    <section ref={raiz} className="lp-secao lp-numeros">
      <div className="lp-wrap">
        <p className="lp-rotulo" style={{ "--cor": "var(--ciano)" } as React.CSSProperties}>
          Já passou pelo caixa das lojas que usam a Ktalogu
        </p>
        {/* O HTML já traz o valor; o script só anima por cima. */}
        <p className="lp-numeros-valor" aria-live="off">
          <span ref={numero}>{inicialFormatado.inteiro}</span>
          <small ref={centavos}>{inicialFormatado.centavos}</small>
        </p>
        <p className="lp-numeros-texto">
          Esse número não é promessa. Ele vem dos pagamentos registrados nas lojas e atualiza sozinho enquanto
          você lê.
        </p>
        <span className="lp-vivo">
          <i aria-hidden="true" />
          Ao vivo
        </span>
      </div>
    </section>
  );
}
