"use client";

// 24'lük listenin gövdesi. Program adı, 2024/2025 tabanları ve ham trend
// herkese görünür. AI gerekçesi ile kişisel risk, kilitliBaslangic sonrasında
// ücretli katman olarak ayrılır; ücretli metin sunucuda zaten maskelidir.

import { Fragment, useEffect, useRef, useState } from "react";
import {
  ChevronDown,
  Lock,
  MapPin,
  Minus,
  Rocket,
  Scale,
  ShieldCheck,
  TrendingDown,
  TrendingUp,
} from "lucide-react";
import { UniLogo } from "@/components/uni-logo";
import type { RaporSonuc } from "@/lib/ai/rapor";
import {
  RISK_ETIKET,
  dilimdenRisk,
  riskHesapla,
  type RiskSeviyesi,
} from "@/lib/risk";

export const DILIM_ETIKET: Record<string, string> = {
  hayal: "Hayal",
  dengeli: "Dengeli",
  garanti: "Garanti",
};

// Risk renk dili: yeşil = güvenli, sarı = az riskli, kırmızı = riskli
const RISK_STIL: Record<
  RiskSeviyesi,
  { nokta: string; kenar: string; icon: typeof Rocket }
> = {
  riskli: { nokta: "bg-red-500", kenar: "border-l-red-500", icon: Rocket },
  "az-riskli": {
    nokta: "bg-amber-500",
    kenar: "border-l-amber-500",
    icon: Scale,
  },
  guvenli: {
    nokta: "bg-emerald-500",
    kenar: "border-l-emerald-500",
    icon: ShieldCheck,
  },
};

const YILLAR = [2021, 2022, 2023, 2024, 2025];

type Trend = "zorlasiyor" | "kolaylasiyor" | "stabil";

/** Deterministik trend: ilk ve son bilinen taban sıralaması kıyaslanır.
 *  Sıralama sayısı küçüldüyse bölüm zorlaşıyor demektir. */
function trendYonu(gecmis?: (number | null)[]): Trend | null {
  const dolu = (gecmis ?? []).filter((s): s is number => s != null);
  if (dolu.length < 2) return null;
  const oran = dolu[dolu.length - 1] / dolu[0];
  if (oran < 0.88) return "zorlasiyor";
  if (oran > 1.14) return "kolaylasiyor";
  return "stabil";
}

const TREND_GORUNUM: Record<
  Trend,
  { icon: typeof Minus; etiket: string; renk: string }
> = {
  zorlasiyor: {
    icon: TrendingUp,
    etiket: "Taban zorlaşıyor",
    renk: "text-red-500",
  },
  kolaylasiyor: {
    icon: TrendingDown,
    etiket: "Taban rahatlıyor",
    renk: "text-emerald-600",
  },
  stabil: { icon: Minus, etiket: "Taban stabil", renk: "text-slate-400" },
};

/** Son 5 yılın taban sıralaması mini çizgisi (detay panelinde). */
function TrendCizgisi({ gecmis }: { gecmis: (number | null)[] }) {
  const noktalar = YILLAR.map((yil, i) => ({ yil, sira: gecmis[i] })).filter(
    (n): n is { yil: number; sira: number } => n.sira != null,
  );
  if (noktalar.length < 2) return null;

  const W = 150;
  const H = 40;
  const min = Math.min(...noktalar.map((n) => n.sira));
  const max = Math.max(...noktalar.map((n) => n.sira));
  const aralik = Math.max(1, max - min);
  // Küçük sıralama = daha zor bölüm = çizgide yukarıda
  const nokta = (i: number, sira: number) => ({
    x: 6 + (i / (noktalar.length - 1)) * (W - 12),
    y: 8 + ((sira - min) / aralik) * (H - 16),
  });
  const path = noktalar
    .map((n, i) => {
      const { x, y } = nokta(i, n.sira);
      return `${i === 0 ? "M" : "L"} ${x.toFixed(1)} ${y.toFixed(1)}`;
    })
    .join(" ");
  const son = nokta(noktalar.length - 1, noktalar[noktalar.length - 1].sira);

  return (
    <div className="mt-2 flex items-center gap-2">
      <svg
        viewBox={`0 0 ${W} ${H}`}
        className="h-10 w-37.5"
        role="img"
        aria-label={`Taban sıralaması ${noktalar[0].yil}: ${noktalar[0].sira.toLocaleString("tr-TR")}, ${noktalar[noktalar.length - 1].yil}: ${noktalar[noktalar.length - 1].sira.toLocaleString("tr-TR")}`}
      >
        <path
          d={path}
          fill="none"
          stroke="oklch(0.623 0.188 259.8)"
          strokeWidth={2}
          strokeLinecap="round"
        />
        <circle cx={son.x} cy={son.y} r={3} fill="oklch(0.623 0.188 259.8)" />
      </svg>
      <span className="text-xs text-slate-500">
        {noktalar[0].yil}: ~{noktalar[0].sira.toLocaleString("tr-TR")}
        <br />
        {noktalar[noktalar.length - 1].yil}: ~
        {noktalar[noktalar.length - 1].sira.toLocaleString("tr-TR")}
      </span>
    </div>
  );
}

export function RaporListesi({
  rapor,
  adaySira,
  kilitliBaslangic,
  kilitOverlay,
  acikSira,
  onHaritadaGor,
}: {
  rapor: RaporSonuc;
  adaySira?: number;
  kilitliBaslangic?: number;
  kilitOverlay?: React.ReactNode;
  /** Dışarıdan (haritadan) açtırılan satır — değişince satır açılıp kaydırılır */
  acikSira?: number | null;
  /** Detaydaki "Haritada gör" — il DB biçiminde */
  onHaritadaGor?: (il: string | null, sira: number) => void;
}) {
  const [acik, setAcik] = useState<Set<number>>(new Set());
  const satirRefs = useRef(new Map<number, HTMLLIElement>());

  // Haritadan gelen seçim: satırı aç ve görünür alana kaydır
  useEffect(() => {
    if (acikSira == null) return;
    // eslint-disable-next-line react-hooks/set-state-in-effect
    setAcik((mevcut) => new Set(mevcut).add(acikSira));
    satirRefs.current
      .get(acikSira)
      ?.scrollIntoView({ behavior: "smooth", block: "center" });
  }, [acikSira]);

  function tiklandi(sira: number) {
    setAcik((mevcut) => {
      const yeni = new Set(mevcut);
      if (yeni.has(sira)) yeni.delete(sira);
      else yeni.add(sira);
      return yeni;
    });
  }

  const kilitIdx = kilitliBaslangic ?? rapor.tercihler.length;

  // Dilim dağılımı: liste hayal diliminden başladığı için ilk ekran hep
  // kırmızı görünür; özet, dengenin sağlıklı olduğunu tek bakışta gösterir.
  const dilimSayilari = rapor.tercihler.reduce(
    (t, x) => {
      t[x.dilim] = (t[x.dilim] ?? 0) + 1;
      return t;
    },
    {} as Record<string, number>,
  );
  const iller = new Set(
    rapor.tercihler
      .map((t) => rapor.programlar[t.programId]?.il)
      .filter((il): il is string => Boolean(il)),
  );
  const tekIl = iller.size === 1 ? [...iller][0] : null;

  const satir = (
    t: RaporSonuc["tercihler"][number],
    index: number,
  ) => {
    const p = rapor.programlar[t.programId];
    const analizKilitli = index >= kilitIdx;
    const risk =
      (adaySira != null ? riskHesapla(p?.efektifSira, adaySira) : null) ??
      dilimdenRisk(t.dilim);
    const stil = RISK_STIL[risk];
    const trend = trendYonu(p?.siraGecmisi);
    const acikMi = acik.has(t.sira);
    const sira2024 = p?.siraGecmisi?.[3] ?? null;
    const sira2025 = p?.siraGecmisi?.[4] ?? null;
    // Son iki yıldan biri eksikse satır başındaki trend rozeti çelişkili
    // okunur ("2025: —" ama "stabil") — rozet ancak iki yıl da doluysa çıkar;
    // uzun vadeli trend detaydaki 2021–2025 çizgisinde durur.
    const trendG =
      trend && sira2024 != null && sira2025 != null
        ? TREND_GORUNUM[trend]
        : null;

    return (
      <li
        key={t.sira}
        ref={(el) => {
          if (el) satirRefs.current.set(t.sira, el);
          else satirRefs.current.delete(t.sira);
        }}
        className={`overflow-hidden rounded-xl border bg-white transition-[border-color,box-shadow] duration-200 hover:border-slate-300 hover:shadow-xs ${
          analizKilitli ? "border-slate-200" : `border-l-4 ${stil.kenar}`
        }`}
      >
        <button
          type="button"
          onClick={() => tiklandi(t.sira)}
          aria-expanded={acikMi}
          className="grid min-h-16 w-full cursor-pointer grid-cols-[auto_minmax(0,1fr)_auto] items-center gap-x-3 px-3 py-2.5 text-left xl:grid-cols-[auto_minmax(220px,1fr)_92px_92px_112px_82px_auto] xl:px-4"
        >
          <span className="flex size-7 shrink-0 items-center justify-center rounded-full bg-slate-100 font-heading text-xs font-bold">
            {t.sira}
          </span>
          <span className="flex min-w-0 items-center gap-2.5">
            {p?.universite ? (
              <UniLogo ad={p.universite} boy="sm" className="hidden sm:flex" />
            ) : null}
            <span className="min-w-0 flex-1">
            <span className="block truncate text-sm font-semibold">
              {p?.isim ?? t.programId}
            </span>
            <span className="block truncate text-xs text-slate-500">
              {p?.universite}
              {p?.il ? ` · ${p.il.toLocaleLowerCase("tr-TR")}` : ""}
            </span>
            <span className="mt-1 flex items-center gap-3 text-[11px] tabular-nums text-slate-500 xl:hidden">
              <span>2024: {sira2024?.toLocaleString("tr-TR") ?? "—"}</span>
              <span>2025: {sira2025?.toLocaleString("tr-TR") ?? "—"}</span>
              {trendG ? <span className={trendG.renk}>{trendG.etiket}</span> : null}
            </span>
            </span>
          </span>
          <span className="hidden text-right text-xs tabular-nums text-slate-600 xl:block">
            {sira2024?.toLocaleString("tr-TR") ?? "—"}
          </span>
          <span className="hidden text-right text-xs font-semibold tabular-nums text-slate-900 xl:block">
            {sira2025?.toLocaleString("tr-TR") ?? "—"}
          </span>
          <span className="hidden items-center gap-1.5 text-xs xl:flex">
            {trendG ? (
              <>
                <trendG.icon className={`size-4 shrink-0 ${trendG.renk}`} aria-hidden />
                <span className={trendG.renk}>
                  {trend === "zorlasiyor"
                    ? "Zorlaşıyor"
                    : trend === "kolaylasiyor"
                      ? "Rahatlıyor"
                      : "Stabil"}
                </span>
              </>
            ) : (
              <span className="text-slate-400">Veri eksik</span>
            )}
          </span>
          <span className="hidden items-center gap-1.5 text-xs font-medium xl:flex">
            {analizKilitli ? (
              <>
                <Lock className="size-3.5 text-slate-400" aria-hidden />
                <span className="text-slate-500">Pakette</span>
              </>
            ) : (
              <>
                <span className={`size-2.5 rounded-full ${stil.nokta}`} aria-hidden />
                <span>{RISK_ETIKET[risk]}</span>
              </>
            )}
          </span>
          <ChevronDown
            className={`size-4 shrink-0 text-slate-400 transition-transform duration-200 ${acikMi ? "rotate-180" : ""}`}
            aria-hidden
          />
        </button>

        {acikMi ? (
          <div className="border-t border-slate-100 bg-slate-50/50 px-4 py-4">
            <div className="mb-2 flex flex-wrap items-center gap-2 text-xs text-slate-500">
              {analizKilitli ? (
                <>
                  <Lock className="size-3.5" aria-hidden />
                  <span className="font-medium">Kişisel analiz pakette</span>
                </>
              ) : (
                <>
                  <stil.icon className="size-3.5" aria-hidden />
                  <span className="font-medium">
                    {DILIM_ETIKET[t.dilim]} · {RISK_ETIKET[risk]}
                  </span>
                </>
              )}
              {p?.unitur ? <span>· {p.unitur}</span> : null}
            </div>
            <dl className="grid gap-2 text-sm sm:grid-cols-3">
              <div className="rounded-lg border border-slate-200 bg-white p-3">
                <dt className="text-xs font-semibold text-slate-500">
                  2021–2025 taban trendi
                </dt>
                <dd className="mt-1 text-slate-700">
                  {p?.siraGecmisi ? (
                    <TrendCizgisi gecmis={p.siraGecmisi} />
                  ) : (
                    "Yeterli veri yok."
                  )}
                </dd>
              </div>
              {analizKilitli ? (
                <div className="flex flex-col justify-center rounded-lg border border-dashed border-slate-300 bg-white p-3 sm:col-span-2">
                  <dt className="flex items-center gap-1.5 text-xs font-semibold text-slate-700">
                    <Lock className="size-3.5" aria-hidden />
                    AI karar desteği
                  </dt>
                  <dd className="mt-1 text-sm text-slate-600">
                    Bu bölümün neden listende olduğunu ve sıralamana özel yerleşme
                    riskini paketle gör.
                  </dd>
                </div>
              ) : (
                <>
                  <div className="rounded-lg border border-slate-200 bg-white p-3">
                    <dt className="text-xs font-semibold text-slate-500">
                      Neden listede?
                    </dt>
                    <dd className="mt-1 text-slate-700">{t.gerekce}</dd>
                  </div>
                  <div className="rounded-lg border border-slate-200 bg-white p-3">
                    <dt className="text-xs font-semibold text-slate-500">
                      Risk ve AI yorumu
                    </dt>
                    <dd className="mt-1 text-slate-700">
                      {t.riskNotu} {t.trendOzeti}
                    </dd>
                  </div>
                </>
              )}
            </dl>
            {onHaritadaGor && p?.il ? (
              <button
                type="button"
                onClick={() => onHaritadaGor(p.il, t.sira)}
                className="mt-3 inline-flex cursor-pointer items-center gap-1.5 text-xs font-medium text-primary transition-colors duration-200 hover:text-primary/80"
              >
                <MapPin className="size-3.5" aria-hidden />
                Haritada gör
              </button>
            ) : null}
          </div>
        ) : null}
      </li>
    );
  };

  return (
    <div>
      <div className="flex flex-wrap items-end justify-between gap-2">
        <div>
          <h2 className="font-heading text-lg font-bold">24 tercihin ve taban verileri</h2>
          <p className="mt-1 text-xs text-slate-500">
            Satıra dokunarak 2021–2025 trendini inceleyebilirsin.
          </p>
        </div>
        {kilitIdx < rapor.tercihler.length ? (
          <p className="text-xs font-medium text-emerald-700">
            Programlar ve ham veriler ücretsiz
          </p>
        ) : null}
      </div>

      <div className="mt-3 flex flex-wrap items-center gap-2 text-xs font-medium">
        {(
          [
            ["hayal", "bg-red-500"],
            ["dengeli", "bg-amber-500"],
            ["garanti", "bg-emerald-500"],
          ] as const
        ).map(([dilim, nokta]) => (
          <span
            key={dilim}
            className="inline-flex items-center gap-1.5 rounded-full border border-slate-200 bg-white px-2.5 py-1 text-slate-700"
          >
            <span className={`size-2 rounded-full ${nokta}`} aria-hidden />
            {dilimSayilari[dilim] ?? 0} {DILIM_ETIKET[dilim].toLocaleLowerCase("tr-TR")}
          </span>
        ))}
        <span className="text-slate-400">
          Liste hayal diliminden başlar; kırmızı satırlar plana dahildir.
        </span>
      </div>

      {tekIl ? (
        <p className="mt-3 rounded-lg border border-amber-200 bg-amber-50 px-3 py-2 text-xs text-amber-900">
          Listenin 24 tercihi de tek şehirde (
          {tekIl.toLocaleLowerCase("tr-TR")}). Boşta kalma riskini azaltmak
          için birkaç farklı şehir eklemeyi düşünebilirsin.
        </p>
      ) : null}

      <div className="mt-4 hidden grid-cols-[auto_minmax(220px,1fr)_92px_92px_112px_82px_auto] gap-x-3 px-4 text-[11px] font-semibold uppercase tracking-wide text-slate-500 xl:grid">
        <span className="w-7">#</span>
        <span>Program</span>
        <span className="text-right">2024 taban</span>
        <span className="text-right">2025 taban</span>
        <span>Ham trend</span>
        <span>AI risk</span>
        <span className="w-4" />
      </div>

      <ol className="mt-2 flex flex-col gap-2">
        {rapor.tercihler.map((t, index) => (
          <Fragment key={t.sira}>
            {index === kilitIdx && kilitOverlay ? (
              <li className="my-2 list-none rounded-2xl border border-orange-200 bg-orange-50/70 p-5">
                {kilitOverlay}
              </li>
            ) : null}
            {satir(t, index)}
          </Fragment>
        ))}
      </ol>
    </div>
  );
}
