"use client";

import { useEffect, useRef, useState } from "react";
import {
  CANLI_ESIGI,
  LISTE_ESIGI,
  esikGecti,
  type SosyalKanitVerisi,
} from "@/lib/sosyal-kanit-sabitler";

/** Sayfa açık kaldıkça canlı sayıyı tazeleyen yoklama aralığı. */
const YOKLAMA_MS = 60_000;
/** Sayacın son değere ulaşma süresi. */
const SAYAC_MS = 900;

function sayi(n: number): string {
  return n.toLocaleString("tr-TR");
}

/**
 * Liste sayısı görünür olunca son değere kadar sayar. SSR HTML'i son değeri
 * taşır (JS'siz istemcide sayı doğru görünür); animasyon yalnızca hareket
 * isteyen istemcide, üstelik yalnızca bir kez çalışır.
 */
function useSayac(hedef: number, ref: React.RefObject<HTMLElement | null>) {
  // null = animasyon çalışmıyor → güncel hedef doğrudan gösterilir. Böylece
  // yoklama sayıyı tazelediğinde sayaç baştan oynamaz, sadece değer değişir.
  const [animasyon, setAnimasyon] = useState<number | null>(null);
  const hedefRef = useRef(hedef);

  useEffect(() => {
    hedefRef.current = hedef;
  }, [hedef]);

  useEffect(() => {
    const el = ref.current;
    if (!el) return;
    if (
      typeof IntersectionObserver === "undefined" ||
      window.matchMedia("(prefers-reduced-motion: reduce)").matches
    ) {
      return;
    }

    let cerceve = 0;
    const io = new IntersectionObserver(
      (girisler) => {
        if (!girisler.some((g) => g.isIntersecting)) return;
        io.disconnect();
        const son = hedefRef.current;
        const basla = performance.now();
        const adim = (simdi: number) => {
          const t = Math.min(1, (simdi - basla) / SAYAC_MS);
          if (t < 1) {
            // easeOutCubic: hızlı başlar, son sayıya yumuşak oturur
            setAnimasyon(Math.round(son * (1 - Math.pow(1 - t, 3))));
            cerceve = requestAnimationFrame(adim);
          } else {
            setAnimasyon(null);
          }
        };
        setAnimasyon(0);
        cerceve = requestAnimationFrame(adim);
      },
      { rootMargin: "0px 0px -60px 0px" },
    );
    io.observe(el);
    return () => {
      io.disconnect();
      cancelAnimationFrame(cerceve);
    };
  }, [ref]);

  return animasyon ?? hedef;
}

export function SosyalKanitGovde({ ilk }: { ilk: SosyalKanitVerisi }) {
  const [veri, setVeri] = useState(ilk);
  const ref = useRef<HTMLDivElement>(null);
  const gosterilenListe = useSayac(veri.liste, ref);

  useEffect(() => {
    // Sekme arkadayken yoklama yok: kimse bakmıyorken sunucuyu meşgul etme.
    let iptal = false;
    let zamanlayici: ReturnType<typeof setTimeout> | undefined;

    async function tazele() {
      try {
        const cevap = await fetch("/api/sosyal-kanit", { cache: "no-store" });
        if (!cevap.ok) return;
        const yeni = (await cevap.json()) as SosyalKanitVerisi;
        if (!iptal) setVeri(yeni);
      } catch {
        // Sessiz: ekrandaki son sayı kalır.
      }
    }

    function planla() {
      clearTimeout(zamanlayici);
      if (document.visibilityState !== "visible") return;
      zamanlayici = setTimeout(() => {
        void tazele().then(planla);
      }, YOKLAMA_MS);
    }

    function gorunurlukDegisti() {
      if (document.visibilityState === "visible") void tazele();
      planla();
    }

    planla();
    document.addEventListener("visibilitychange", gorunurlukDegisti);
    return () => {
      iptal = true;
      clearTimeout(zamanlayici);
      document.removeEventListener("visibilitychange", gorunurlukDegisti);
    };
  }, []);

  if (!esikGecti(veri.liste, LISTE_ESIGI)) return null;

  const canliVar = veri.canli !== null && esikGecti(veri.canli, CANLI_ESIGI);

  return (
    <div
      ref={ref}
      className="rounded-xl border border-slate-200/70 bg-slate-50/80 px-4 py-3.5"
    >
      <p className="flex flex-wrap items-baseline gap-x-2 gap-y-0.5">
        <span className="font-heading text-3xl font-bold tabular-nums leading-none text-slate-900">
          {sayi(gosterilenListe)}
        </span>
        <span className="text-sm leading-snug text-slate-600">
          öğrenci listesini KolayTercih ile oluşturdu
        </span>
      </p>

      {canliVar ? (
        <p className="mt-3 flex items-center gap-2 border-t border-slate-200/70 pt-3 text-sm text-slate-600">
          <span className="relative flex size-2.5 shrink-0">
            <span className="absolute inline-flex size-full rounded-full bg-emerald-400 opacity-70 motion-safe:animate-ping" />
            <span className="relative inline-flex size-2.5 rounded-full bg-emerald-500" />
          </span>
          <span>
            şu anda{" "}
            <strong className="font-semibold tabular-nums text-slate-900">
              {sayi(veri.canli as number)}
            </strong>{" "}
            kişi KolayTercih ile tercihini planlıyor
          </span>
        </p>
      ) : null}
    </div>
  );
}
