"use client";

// /meraklisina'nın canlı anlatım katmanı: kullanıcı kendi sıralamasını girer,
// dilim şeridi ve kademeli filtre hunisi o sıralamanın GERÇEK sayılarıyla
// güncellenir. Provider sayfadaki metin bölümlerini (RSC children) sarar;
// görseller context'ten okur, böylece tek girişle iki diyagram birden yaşar.

import {
  createContext,
  useContext,
  useEffect,
  useRef,
  useState,
  type ReactNode,
} from "react";
import type { DilimKey, SihirbazFacetleri } from "@/lib/db";

const TUR_SECENEKLERI = [
  { deger: "say", etiket: "Sayısal" },
  { deger: "ea", etiket: "Eşit Ağırlık" },
  { deger: "soz", etiket: "Sözel" },
  { deger: "dil", etiket: "Dil" },
  { deger: "tyt", etiket: "TYT" },
] as const;

export type DemoVeri = {
  facetler: SihirbazFacetleri;
  dilimToplam: Record<DilimKey, number>;
};

type DemoDurum = {
  sira: number;
  tur: string;
  veri: DemoVeri;
  yukleniyor: boolean;
  // Huni seçimleri ve kademeli facet cevapları
  kategori: string | null;
  il: string | null;
  tip: "devlet" | "vakif" | null;
  kategoriFacet: SihirbazFacetleri | null; // ?kategori= cevabı (iller buradan)
  ilFacet: SihirbazFacetleri | null; // ?kategori&il cevabı (tipler buradan)
  kategoriSec: (k: string | null) => void;
  ilSec: (i: string | null) => void;
  tipSec: (t: "devlet" | "vakif" | null) => void;
  siraDegistir: (ham: string) => void;
  turDegistir: (t: string) => void;
  siraMetni: string;
};

const DemoContext = createContext<DemoDurum | null>(null);

function useDemo(): DemoDurum {
  const ctx = useContext(DemoContext);
  if (!ctx) throw new Error("Demo bileşenleri SiralamaDemo içinde kullanılmalı");
  return ctx;
}

async function facetGetir(
  sira: number,
  tur: string,
  secim: { kategori?: string; il?: string; dilimler?: boolean },
  signal: AbortSignal,
): Promise<{ facetler: SihirbazFacetleri; dilimToplam?: Record<DilimKey, number> } | null> {
  const params = new URLSearchParams({ sira: String(sira), tur });
  if (secim.kategori) params.append("kategori", secim.kategori);
  if (secim.il) params.append("il", secim.il);
  if (secim.dilimler) params.set("dilimler", "1");
  try {
    const res = await fetch(`/api/facetler?${params}`, { signal });
    if (!res.ok) return null;
    return (await res.json()) as {
      facetler: SihirbazFacetleri;
      dilimToplam?: Record<DilimKey, number>;
    };
  } catch {
    return null;
  }
}

export function SiralamaDemo({
  baslangicSira,
  baslangicVeri,
  children,
}: {
  baslangicSira: number;
  baslangicVeri: DemoVeri;
  children: ReactNode;
}) {
  const [siraMetni, setSiraMetni] = useState(
    baslangicSira.toLocaleString("tr-TR"),
  );
  const [sira, setSira] = useState(baslangicSira);
  const [tur, setTur] = useState("say");
  const [veri, setVeri] = useState(baslangicVeri);
  const [yukleniyor, setYukleniyor] = useState(false);
  const [kategori, setKategori] = useState<string | null>(null);
  const [il, setIl] = useState<string | null>(null);
  const [tip, setTip] = useState<"devlet" | "vakif" | null>(null);
  const [kategoriFacet, setKategoriFacet] = useState<SihirbazFacetleri | null>(
    null,
  );
  const [ilFacet, setIlFacet] = useState<SihirbazFacetleri | null>(null);
  const zamanlayici = useRef<ReturnType<typeof setTimeout> | null>(null);

  // Sıralama/tür değişti → ana veriyi tazele, huni seçimlerini sıfırla
  useEffect(() => {
    if (sira === baslangicSira && tur === "say" && veri === baslangicVeri) {
      return; // ilk render: sunucudan gelen veri zaten güncel
    }
    const ctrl = new AbortController();
    // eslint-disable-next-line react-hooks/set-state-in-effect -- fetch başlangıç işareti
    setYukleniyor(true);
    setKategori(null);
    setIl(null);
    setTip(null);
    setKategoriFacet(null);
    setIlFacet(null);
    facetGetir(sira, tur, { dilimler: true }, ctrl.signal)
      .then((cevap) => {
        if (!cevap?.dilimToplam) return;
        setVeri({ facetler: cevap.facetler, dilimToplam: cevap.dilimToplam });
      })
      .finally(() => setYukleniyor(false));
    return () => ctrl.abort();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [sira, tur]);

  // Kategori seçildi → o kategorinin illerini getir
  useEffect(() => {
    if (!kategori) return;
    const ctrl = new AbortController();
    facetGetir(sira, tur, { kategori }, ctrl.signal).then((cevap) => {
      if (cevap) setKategoriFacet(cevap.facetler);
    });
    return () => ctrl.abort();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [kategori]);

  // İl seçildi → kategori+il ile tipleri getir
  useEffect(() => {
    if (!kategori || !il) return;
    const ctrl = new AbortController();
    facetGetir(sira, tur, { kategori, il }, ctrl.signal).then((cevap) => {
      if (cevap) setIlFacet(cevap.facetler);
    });
    return () => ctrl.abort();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [kategori, il]);

  function siraDegistir(ham: string) {
    const rakamlar = ham.replace(/\D/g, "").slice(0, 7);
    setSiraMetni(rakamlar ? Number(rakamlar).toLocaleString("tr-TR") : "");
    if (zamanlayici.current) clearTimeout(zamanlayici.current);
    const deger = Number(rakamlar);
    if (!deger || deger < 1 || deger > 4_000_000) return;
    zamanlayici.current = setTimeout(() => setSira(deger), 450);
  }

  const durum: DemoDurum = {
    sira,
    tur,
    veri,
    yukleniyor,
    kategori,
    il,
    tip,
    kategoriFacet,
    ilFacet,
    kategoriSec: (k) => {
      setKategori(k);
      setIl(null);
      setTip(null);
      setKategoriFacet(null);
      setIlFacet(null);
    },
    ilSec: (i) => {
      setIl(i);
      setTip(null);
      setIlFacet(null);
    },
    tipSec: setTip,
    siraDegistir,
    turDegistir: setTur,
    siraMetni,
  };

  return <DemoContext.Provider value={durum}>{children}</DemoContext.Provider>;
}

/** Sıralama girişi + puan türü — iki diyagramı birden süren tek kumanda. */
export function DemoKumanda() {
  const { siraMetni, siraDegistir, tur, turDegistir, sira, yukleniyor } =
    useDemo();
  return (
    <div className="rounded-2xl border border-primary/20 bg-primary/5 p-5">
      <label
        htmlFor="demo-sira"
        className="font-heading text-sm font-bold text-slate-900"
      >
        Kendi sıralamanı gir, aşağıdaki görseller sana göre değişsin
      </label>
      <div className="mt-3 flex flex-col gap-3 sm:flex-row sm:items-center">
        <input
          id="demo-sira"
          inputMode="numeric"
          autoComplete="off"
          value={siraMetni}
          onChange={(e) => siraDegistir(e.target.value)}
          placeholder="ör. 85.000"
          className="h-11 w-full rounded-xl border border-slate-200 bg-white px-4 text-base font-medium tabular-nums outline-none transition-colors focus:border-primary sm:w-44"
        />
        <div
          role="radiogroup"
          aria-label="Puan türü"
          className="flex flex-wrap gap-1.5"
        >
          {TUR_SECENEKLERI.map((t) => (
            <button
              key={t.deger}
              type="button"
              role="radio"
              aria-checked={tur === t.deger}
              onClick={() => turDegistir(t.deger)}
              className={
                tur === t.deger
                  ? "cursor-pointer rounded-full border border-primary bg-primary px-3 py-1.5 text-xs font-medium text-white"
                  : "cursor-pointer rounded-full border border-slate-200 bg-white px-3 py-1.5 text-xs text-slate-600 transition-colors duration-200 hover:border-slate-300"
              }
            >
              {t.etiket}
            </button>
          ))}
        </div>
      </div>
      <p
        className={`mt-2 text-xs text-slate-500 ${yukleniyor ? "animate-pulse" : ""}`}
        aria-live="polite"
      >
        {yukleniyor
          ? "Hesaplanıyor…"
          : `Aşağıdaki tüm sayılar ${sira.toLocaleString("tr-TR")}. sıradaki bir aday için gerçek YÖK Atlas verisidir.`}
      </p>
    </div>
  );
}

/** Sıralama ekseni: girilen sıraya göre dilim sınırları ve gerçek adetler. */
export function DilimSeridiCanli() {
  const { sira, veri, yukleniyor } = useDemo();
  const t = veri.dilimToplam;
  const dengeliUst = Math.round(sira * 1.4);
  const fmt = (n: number) => n.toLocaleString("tr-TR");

  return (
    <figure className={`mt-6 ${yukleniyor ? "animate-pulse opacity-60" : ""}`}>
      <svg
        viewBox="0 0 640 168"
        role="img"
        aria-label={`Sıralama ekseni: ${fmt(sira)}. sıradaki aday için Hayal diliminde ${fmt(t.hayal)}, Dengeli diliminde ${fmt(t.dengeli)}, Garanti diliminde ${fmt(t.garanti)} program var.`}
        className="w-full"
      >
        {/* eksen */}
        <line
          x1="20"
          y1="86"
          x2="620"
          y2="86"
          stroke="currentColor"
          className="text-slate-300"
          strokeWidth="2"
        />
        <text x="20" y="150" className="fill-slate-400 text-[11px]">
          1. sıra (en iyi)
        </text>
        <text
          x="620"
          y="150"
          textAnchor="end"
          className="fill-slate-400 text-[11px]"
        >
          taban sıralaması büyüdükçe →
        </text>

        {/* hayal */}
        <rect x="20" y="70" width="150" height="32" rx="4" className="fill-red-100" />
        <text x="95" y="40" textAnchor="middle" className="fill-red-600 text-[12px] font-semibold">
          Hayal
        </text>
        <text x="95" y="56" textAnchor="middle" className="fill-slate-600 text-[11px] font-medium tabular-nums">
          {fmt(t.hayal)} program
        </text>
        <text x="95" y="123" textAnchor="middle" className="fill-slate-500 text-[10px]">
          tabanı senden iyi
        </text>

        {/* aday işareti */}
        <line x1="172" y1="24" x2="172" y2="112" stroke="currentColor" className="text-slate-900" strokeWidth="2" strokeDasharray="4 3" />
        <text x="172" y="16" textAnchor="middle" className="fill-slate-900 text-[12px] font-bold">
          SEN · {fmt(sira)}.
        </text>

        {/* dengeli */}
        <rect x="174" y="70" width="120" height="32" rx="4" className="fill-amber-100" />
        <text x="234" y="40" textAnchor="middle" className="fill-amber-600 text-[12px] font-semibold">
          Dengeli
        </text>
        <text x="234" y="56" textAnchor="middle" className="fill-slate-600 text-[11px] font-medium tabular-nums">
          {fmt(t.dengeli)} program
        </text>
        <text x="234" y="123" textAnchor="middle" className="fill-slate-500 text-[10px]">
          {fmt(sira)}. – {fmt(dengeliUst)}. arası taban
        </text>

        {/* garanti */}
        <rect x="296" y="70" width="324" height="32" rx="4" className="fill-emerald-100" />
        <text x="458" y="40" textAnchor="middle" className="fill-emerald-700 text-[12px] font-semibold">
          Garanti
        </text>
        <text x="458" y="56" textAnchor="middle" className="fill-slate-600 text-[11px] font-medium tabular-nums">
          {fmt(t.garanti)} program
        </text>
        <text x="458" y="123" textAnchor="middle" className="fill-slate-500 text-[10px]">
          {fmt(dengeliUst + 1)}. sonrası — sonu yok, sayfaladıkça uzar
        </text>
      </svg>
      <figcaption className="mt-2 text-xs text-slate-500">
        Liste her dilimde{" "}
        <span className="font-medium text-slate-700">
          sana en yakın tabandan uzağa doğru
        </span>{" "}
        sıralanır; &ldquo;Daha fazla göster&rdquo; dedikçe uzaktakiler gelir.
      </figcaption>
    </figure>
  );
}

function HuniCubugu({
  etiket,
  adet,
  oran,
}: {
  etiket: string;
  adet: number;
  oran: number;
}) {
  return (
    <div className="min-w-0 flex-1">
      <div
        className="flex h-9 min-w-36 items-center justify-between gap-2 rounded-lg bg-primary/85 px-3 transition-[width] duration-300"
        style={{ width: `${Math.min(Math.max(oran * 100, 36), 100)}%` }}
      >
        <span className="truncate text-xs font-medium text-white">{etiket}</span>
        <span className="shrink-0 text-xs font-bold tabular-nums text-white">
          {adet.toLocaleString("tr-TR")}
        </span>
      </div>
    </div>
  );
}

function SecimCipleri<T extends { anahtar: string; etiket: string; adet: number }>({
  secenekler,
  secili,
  onSec,
}: {
  secenekler: T[];
  secili: string | null;
  onSec: (anahtar: string | null) => void;
}) {
  return (
    <div className="flex flex-wrap gap-1.5">
      {secenekler.map((s) => (
        <button
          key={s.anahtar}
          type="button"
          aria-pressed={secili === s.anahtar}
          onClick={() => onSec(secili === s.anahtar ? null : s.anahtar)}
          className={
            secili === s.anahtar
              ? "cursor-pointer rounded-full border border-orange-500 bg-orange-500 px-3 py-1.5 text-xs font-medium text-white"
              : "cursor-pointer rounded-full border border-slate-200 bg-white px-3 py-1.5 text-xs text-slate-600 transition-colors duration-200 hover:border-slate-300"
          }
        >
          {s.etiket}
          <span className="ml-1 text-[10px] opacity-70 tabular-nums">
            {s.adet.toLocaleString("tr-TR")}
          </span>
        </button>
      ))}
    </div>
  );
}

// AI listesinin dilim iskeleti: üstte hayal, ortada dengeli, sonda garanti.
// Ürünün risk renkleriyle boyanır; sayılar prompt'taki kuralın orta değeri.
const LISTE_ISKELETI: { dilim: string; adet: number; renk: string }[] = [
  { dilim: "hayal", adet: 5, renk: "bg-red-400" },
  { dilim: "dengeli", adet: 13, renk: "bg-amber-400" },
  { dilim: "garanti", adet: 6, renk: "bg-emerald-500" },
];

/** Huninin finali: kalan havuzun yapay zekâya gidişi ve 24'lük listenin
    iskeleti. Havuz 24'ün altına düşerse gevşetme kuralını canlı gösterir. */
function YapayZekaAsamasi({ havuz }: { havuz: number }) {
  const dar = havuz < 24;
  return (
    <div className="border-t border-slate-100 pt-4">
      <p className="text-xs font-semibold text-slate-500">
        Sonra sıra yapay zekâda
      </p>
      <p className="mt-1.5 text-xs leading-5 text-slate-600">
        Seçimlerinden geriye kalan{" "}
        <span className="font-bold tabular-nums text-slate-900">
          {havuz.toLocaleString("tr-TR")} programlık havuz
        </span>{" "}
        yapay zekâya gider; o da bu havuzdan tam 24 tercih seçer ve şu iskelete
        oturtur:
      </p>

      {/* 24 hücrelik liste şeridi — renk + metin birlikte (renk tek başına
          anlam taşımaz) */}
      <div
        role="img"
        aria-label="24 tercihlik listenin yapısı: en üstte yaklaşık 5 hayal, ortada 13 dengeli, sonda 6 garanti tercih."
        className="mt-3"
      >
        <div className="flex gap-1">
          {LISTE_ISKELETI.flatMap((b) =>
            Array.from({ length: b.adet }, (_, i) => (
              <span
                key={`${b.dilim}-${i}`}
                className={`h-6 min-w-0 flex-1 rounded ${b.renk}`}
              />
            )),
          )}
        </div>
        <div className="mt-1.5 flex justify-between text-[11px] text-slate-500">
          <span>
            üstte 4–6 <span className="font-semibold text-red-600">hayal</span>
          </span>
          <span>
            ortada 12–14{" "}
            <span className="font-semibold text-amber-600">dengeli</span>
          </span>
          <span>
            sonda 5–7{" "}
            <span className="font-semibold text-emerald-600">garanti</span>
          </span>
        </div>
      </div>

      <ul className="mt-3 space-y-1 text-xs leading-5 text-slate-600">
        <li>
          · Havuzda olmayan bir bölümü yazamaz — listedeki her satırın kimliği
          havuzla karşılaştırılır, uymayan liste yeniden ürettirilir.
        </li>
        <li>
          · Her satıra tek cümlelik gerekçe ve bir risk notu ekler; sıraya neyi
          neden koyduğu görünür.
        </li>
        <li>
          · Önceliklerin (iş garantisi, maaş, prestij…) hangi programın öne
          geçeceğini belirler.
        </li>
        <li>
          · Havuz 24&apos;ün altına düşerse filtreler adım adım gevşetilir —
          önce il, sonra alan — ve bu, listende açıkça belirtilir.
        </li>
      </ul>

      {dar ? (
        <p className="mt-3 rounded-lg bg-amber-50 px-3 py-2 text-xs leading-5 text-amber-700">
          Bu seçimle havuz 24&apos;ün altına düştü. Gerçek sihirbaz bu durumda
          filtreleri adım adım gevşetir — önce il, sonra alan tercihi esnetilir
          — ve bunu listende açıkça belirtir; liste her zaman 24&apos;e
          tamamlanır.
        </p>
      ) : null}
    </div>
  );
}

/** Kademeli filtre hunisi: gerçek sihirbaz mantığının oynanabilir kopyası. */
export function HuniCanli() {
  const {
    veri,
    yukleniyor,
    kategori,
    il,
    tip,
    kategoriFacet,
    ilFacet,
    kategoriSec,
    ilSec,
    tipSec,
  } = useDemo();

  const toplam = veri.facetler.toplam;
  const kategoriAdet =
    kategori != null
      ? (veri.facetler.kategoriler.find((k) => k.ad === kategori)?.adet ?? 0)
      : null;
  const ilAdet =
    il != null && kategoriFacet
      ? (kategoriFacet.iller.find((i) => i.il === il)?.adet ?? 0)
      : null;
  const tipAdet =
    tip != null && ilFacet
      ? (ilFacet.uniturler.find((u) => u.grup === tip)?.adet ?? 0)
      : null;

  const kategoriSecenekleri = veri.facetler.kategoriler.slice(0, 6).map((k) => ({
    anahtar: k.ad,
    etiket: k.ad,
    adet: k.adet,
  }));
  const ilSecenekleri = (kategoriFacet?.iller ?? []).slice(0, 6).map((i) => ({
    anahtar: i.il,
    etiket: i.il.toLocaleLowerCase("tr-TR"),
    adet: i.adet,
  }));
  const tipSecenekleri = (ilFacet?.uniturler ?? []).map((u) => ({
    anahtar: u.grup,
    etiket: u.grup === "devlet" ? "Devlet" : "Vakıf",
    adet: u.adet,
  }));

  // Yapay zekâya giden havuz: huninin en derin (en son seçilmiş) katmanı
  const havuz = tipAdet ?? ilAdet ?? kategoriAdet ?? toplam;

  return (
    <div
      className={`mt-6 space-y-4 rounded-2xl border border-slate-200 bg-white p-5 ${
        yukleniyor ? "animate-pulse opacity-60" : ""
      }`}
    >
      {/* Huni çubukları — her seçim bir çubuk daha ekler */}
      <div className="space-y-2">
        <div className="flex items-center gap-3">
          <span className="w-6 shrink-0" />
          <HuniCubugu
            etiket="Sıralamanla açılan tüm programlar"
            adet={toplam}
            oran={1}
          />
        </div>
        {kategori != null && kategoriAdet != null ? (
          <div className="flex items-center gap-3">
            <span className="w-6 shrink-0 text-right text-xs font-bold text-slate-400">
              1.
            </span>
            <HuniCubugu
              etiket={`“${kategori}” seçince`}
              adet={kategoriAdet}
              oran={toplam > 0 ? kategoriAdet / toplam : 0}
            />
          </div>
        ) : null}
        {il != null && ilAdet != null ? (
          <div className="flex items-center gap-3">
            <span className="w-6 shrink-0 text-right text-xs font-bold text-slate-400">
              2.
            </span>
            <HuniCubugu
              etiket={`+ “${il.toLocaleLowerCase("tr-TR")}” seçince`}
              adet={ilAdet}
              oran={toplam > 0 ? ilAdet / toplam : 0}
            />
          </div>
        ) : null}
        {tip != null && tipAdet != null ? (
          <div className="flex items-center gap-3">
            <span className="w-6 shrink-0 text-right text-xs font-bold text-slate-400">
              3.
            </span>
            <HuniCubugu
              etiket={`+ “${tip === "devlet" ? "Devlet" : "Vakıf"}” seçince`}
              adet={tipAdet}
              oran={toplam > 0 ? tipAdet / toplam : 0}
            />
          </div>
        ) : null}
      </div>

      {/* Seçim adımları — sihirbazın küçük, oynanabilir hali */}
      <div className="space-y-3 border-t border-slate-100 pt-4">
        <div>
          <p className="mb-1.5 text-xs font-semibold text-slate-500">
            1. Bir alan seç
          </p>
          <SecimCipleri
            secenekler={kategoriSecenekleri}
            secili={kategori}
            onSec={kategoriSec}
          />
        </div>
        {kategori != null ? (
          <div>
            <p className="mb-1.5 text-xs font-semibold text-slate-500">
              2. Bir il seç{" "}
              <span className="font-normal text-slate-400">
                (iller artık yalnızca “{kategori}” programlarını sayıyor)
              </span>
            </p>
            {ilSecenekleri.length > 0 ? (
              <SecimCipleri
                secenekler={ilSecenekleri}
                secili={il}
                onSec={ilSec}
              />
            ) : (
              <p className="text-xs text-slate-400">Yükleniyor…</p>
            )}
          </div>
        ) : null}
        {kategori != null && il != null ? (
          <div>
            <p className="mb-1.5 text-xs font-semibold text-slate-500">
              3. Üniversite tipi seç{" "}
              <span className="font-normal text-slate-400">
                (sayılar hem alanı hem ili hesaba katıyor)
              </span>
            </p>
            {tipSecenekleri.length > 0 ? (
              <SecimCipleri
                secenekler={tipSecenekleri}
                secili={tip}
                onSec={(t) => tipSec(t as "devlet" | "vakif" | null)}
              />
            ) : (
              <p className="text-xs text-slate-400">Yükleniyor…</p>
            )}
          </div>
        ) : null}
      </div>

      <YapayZekaAsamasi havuz={havuz} />
    </div>
  );
}
