"use client";

import { useEffect, useRef, useState } from "react";
import type { Impact } from "@/types/impact";
import styles from "./ImpactCounter.module.css";

interface Chiffre {
  valeur: number;
  suffixe?: string;
  label: string;
}

function construireChiffres(impact: Impact): Chiffre[] {
  return [
    { valeur: impact.sacsDistribues, label: "sacs biodégradables distribués" },
    { valeur: Math.round(impact.kgPlastiqueEvites), suffixe: " kg", label: "de plastique évités" },
    { valeur: impact.pointsDeVente, label: "points de vente partenaires" },
    { valeur: impact.villes, label: "villes couvertes" },
  ];
}

function useCompteur(cible: number, actif: boolean, dureeMs = 1500) {
  const [valeur, setValeur] = useState(0);

  useEffect(() => {
    if (!actif) return;

    let frame: number;
    const debut = performance.now();

    const tick = (maintenant: number) => {
      const progression = Math.min((maintenant - debut) / dureeMs, 1);
      setValeur(Math.round(cible * progression));
      if (progression < 1) {
        frame = requestAnimationFrame(tick);
      }
    };

    frame = requestAnimationFrame(tick);
    return () => cancelAnimationFrame(frame);
  }, [actif, cible, dureeMs]);

  return valeur;
}

export default function ImpactCounter({ impact }: { impact: Impact }) {
  const ref = useRef<HTMLDivElement>(null);
  const [visible, setVisible] = useState(false);
  const chiffres = construireChiffres(impact);

  useEffect(() => {
    const element = ref.current;
    if (!element) return;

    const observer = new IntersectionObserver(
      ([entry]) => {
        if (entry.isIntersecting) {
          setVisible(true);
          observer.disconnect();
        }
      },
      { threshold: 0.3 },
    );

    observer.observe(element);
    return () => observer.disconnect();
  }, []);

  return (
    <section className={styles.section} ref={ref}>
      <div className={styles.grille}>
        {chiffres.map((chiffre) => (
          <ChiffreItem key={chiffre.label} chiffre={chiffre} actif={visible} />
        ))}
      </div>
    </section>
  );
}

function ChiffreItem({ chiffre, actif }: { chiffre: Chiffre; actif: boolean }) {
  const valeur = useCompteur(chiffre.valeur, actif);

  return (
    <div className={styles.item}>
      <span className={styles.valeur}>
        {valeur.toLocaleString("fr-FR")}
        {chiffre.suffixe}
      </span>
      <span className={styles.label}>{chiffre.label}</span>
    </div>
  );
}
