"use client";

// Sonuç sayfasının AI'sız ham listesi: yalnızca başarı sıralamasıyla
// yokatlas'tan gelen programlar, dilim sekmeleri halinde. Her satırın "+"
// butonu programı manuel 24'lük listeye ekler (bkz. manuel-liste/store).

import { useState } from "react";
import Link from "next/link";
import { useLinkStatus } from "next/link";
import {
  Check,
  Plus,
  Rocket,
  Scale,
  ShieldCheck,
  TrendingDown,
  TrendingUp,
} from "lucide-react";
import type { Program, PuanTuruKey, RankResults } from "@/lib/db";
import { riskHesapla, type RiskSeviyesi } from "@/lib/risk";
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "@/components/ui/table";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import {
  MANUEL_LISTE_MAX,
  ekle,
  useManuelListe,
  type ManuelTercih,
} from "@/components/manuel-liste/store";
import { ManuelHarita } from "@/components/manuel-liste/manuel-harita";

type DilimKey = keyof RankResults;

const DILIMLER: {
  key: DilimKey;
  etiket: string;
  aciklama: string;
  icon: typeof Rocket;
  renk: string;
}[] = [
  {
    key: "hayal",
    etiket: "Hayal",
    aciklama: "Tabanı sıralamanın üstünde — şansını denediğin satırlar.",
    icon: Rocket,
    renk: "text-red-500",
  },
  {
    key: "dengeli",
    etiket: "Dengeli",
    aciklama: "Tabanı sıralamana denk — listenin bel kemiği.",
    icon: Scale,
    renk: "text-amber-500",
  },
  {
    key: "garanti",
    etiket: "Garanti",
    aciklama: "Tabanı belirgin şekilde altında — güvenli bölge.",
    icon: ShieldCheck,
    renk: "text-emerald-600",
  },
];

const RISK_NOKTA: Record<RiskSeviyesi, string> = {
  guvenli: "bg-emerald-500",
  "az-riskli": "bg-amber-500",
  riskli: "bg-red-500",
};

// Seçicideki kısa etiketler — sayfa başlığındaki uzun hallerinden bağımsız
const TUR_ETIKETLERI: Record<PuanTuruKey, string> = {
  say: "Sayısal",
  ea: "Eşit Ağırlık",
  soz: "Sözel",
  dil: "Dil",
  tyt: "TYT",
};

// useLinkStatus Link'in altındaki bir bileşende çağrılmalı; sunucu
// gidiş-dönüşü sürerken tıklanan pill hafifçe nabız atar (layout shift yok).
function SeciciEtiket({ children }: { children: React.ReactNode }) {
  const { pending } = useLinkStatus();
  return (
    <span
      className={`transition-opacity duration-150 ${
        pending ? "animate-pulse opacity-60" : ""
      }`}
    >
      {children}
    </span>
  );
}

function PuanTuruSecici({
  sira,
  aktif,
}: {
  sira: number;
  aktif: PuanTuruKey;
}) {
  return (
    <nav
      aria-label="Puan türü"
      className="flex w-fit max-w-full flex-wrap gap-1 rounded-full border border-slate-200 bg-slate-100 p-1"
    >
      {(Object.keys(TUR_ETIKETLERI) as PuanTuruKey[]).map((key) => (
        <Link
          key={key}
          href={`/sonuc?sira=${sira}&tur=${key}`}
          scroll={false}
          aria-current={key === aktif ? "page" : undefined}
          className={`cursor-pointer rounded-full px-3 py-1.5 text-xs font-medium transition-[background-color,color,transform] duration-150 active:scale-[0.97] ${
            key === aktif
              ? "bg-white text-slate-900 shadow-sm"
              : "text-slate-500 hover:text-slate-900"
          }`}
        >
          <SeciciEtiket>{TUR_ETIKETLERI[key]}</SeciciEtiket>
        </Link>
      ))}
    </nav>
  );
}

function efektifSira(p: Program): number | null {
  return p.sira2025 ?? p.sira2024;
}

function tercihYap(p: Program, adaySira: number): ManuelTercih {
  const taban = efektifSira(p);
  return {
    id: p.id,
    isim: p.isim,
    universite: p.universite,
    il: p.il,
    efektifSira: taban,
    risk: riskHesapla(taban, adaySira),
  };
}

export function ProgramTablosu({
  sonuclar,
  adaySira,
  tur,
}: {
  sonuclar: RankResults;
  adaySira: number;
  tur: PuanTuruKey;
}) {
  const liste = useManuelListe();
  const [aktifDilim, setAktifDilim] = useState<DilimKey>("dengeli");
  const listedekiler = new Set(liste.map((t) => t.id));
  const doldu = liste.length >= MANUEL_LISTE_MAX;

  function eklemeyiDene(p: Program) {
    ekle(tercihYap(p, adaySira));
  }

  return (
    <section className="mt-16" aria-label="Sıralamanla açılan programlar">
      <div>
        <h2 className="font-heading text-2xl font-bold">
          Sıralamanla açılan programlar
        </h2>
        <p className="mt-1 max-w-2xl text-sm text-slate-500">
          Yapay zekâsız, ham YÖK Atlas verisi: geçen yılın taban
          sıralamalarına göre ulaşabildiğin bölümler.{" "}
          <span className="font-medium text-slate-700">
            ＋ ile beğendiklerini Seçtiklerim&apos;e at.
          </span>
        </p>
      </div>

      {/* Listendeki üniversitelerin konumu — ekledikçe canlı dolar */}
      <div className="mt-5">
        <ManuelHarita />
      </div>

      <Tabs
        value={aktifDilim}
        onValueChange={(v) => setAktifDilim(v as DilimKey)}
        className="mt-5"
      >
        {/* Kontrol çubuğu: tabloyu süzen her şey tablonun hemen üstünde —
            solda dilim sekmeleri (birincil), sağda puan türü (ikincil filtre).
            Dar ekranda alt alta sarar. */}
        <div className="flex flex-wrap items-center justify-between gap-x-6 gap-y-3">
          <TabsList>
            {DILIMLER.map((d) => (
              <TabsTrigger key={d.key} value={d.key} className="cursor-pointer">
                <d.icon className={`size-3.5 ${d.renk}`} aria-hidden />
                {d.etiket}
                <span className="text-xs tabular-nums text-slate-400">
                  {sonuclar[d.key].length}
                </span>
              </TabsTrigger>
            ))}
          </TabsList>
          <div className="flex items-center gap-2">
            <span className="text-[11px] font-medium uppercase tracking-wide text-slate-400">
              Puan türü
            </span>
            {/* scroll={false}: tür değişince sayfa konumu korunur */}
            <PuanTuruSecici sira={adaySira} aktif={tur} />
          </div>
        </div>

        {DILIMLER.map((d) => (
          <TabsContent key={d.key} value={d.key}>
            <p className="mt-2 text-xs text-slate-500">{d.aciklama}</p>
            <div className="mt-3 overflow-hidden rounded-2xl border border-slate-200 bg-white">
              {sonuclar[d.key].length === 0 ? (
                <p className="px-5 py-8 text-center text-sm text-slate-500">
                  Bu dilimde filtrene uyan program bulunamadı.
                </p>
              ) : (
                <Table>
                  <TableHeader>
                    <TableRow>
                      <TableHead className="w-8" />
                      <TableHead>Program</TableHead>
                      <TableHead className="hidden text-right md:table-cell">
                        Son 5 yıl
                      </TableHead>
                      <TableHead className="hidden text-right sm:table-cell">
                        Kontenjan
                      </TableHead>
                      <TableHead className="text-right">Taban sıra</TableHead>
                      <TableHead className="w-16 text-right">
                        <span className="sr-only">Listeye ekle</span>
                      </TableHead>
                    </TableRow>
                  </TableHeader>
                  <TableBody>
                    {sonuclar[d.key].map((p) => (
                      <ProgramSatiri
                        key={p.id}
                        program={p}
                        adaySira={adaySira}
                        listede={listedekiler.has(p.id)}
                        doldu={doldu}
                        onEkle={eklemeyiDene}
                      />
                    ))}
                  </TableBody>
                </Table>
              )}
            </div>
          </TabsContent>
        ))}
      </Tabs>
    </section>
  );
}

// Tabanın 2021–2025 seyri: küçük sıra = daha rekabetçi olduğundan y ekseni
// ters çevrilir; çizgi yukarı gidiyorsa bölüm yıllar içinde zorlaşıyor demektir.
function SiraGecmisi({ p }: { p: Program }) {
  const yillar = [
    [2021, p.sira2021],
    [2022, p.sira2022],
    [2023, p.sira2023],
    [2024, p.sira2024],
    [2025, p.sira2025],
  ].filter((y): y is [number, number] => y[1] != null);
  if (yillar.length < 2) return <span className="text-slate-400">—</span>;

  const siralar = yillar.map(([, s]) => s);
  const min = Math.min(...siralar);
  const max = Math.max(...siralar);
  const W = 56;
  const H = 18;
  const PAD = 2;
  const noktalar = yillar.map(([yil, s], i) => {
    const x = PAD + (i / (yillar.length - 1)) * (W - PAD * 2);
    // min sıra (en rekabetçi) üstte dursun
    const y =
      max === min
        ? H / 2
        : PAD + ((s - min) / (max - min)) * (H - PAD * 2);
    return { x, y, yil, s };
  });
  const son = noktalar[noktalar.length - 1];
  const ozet = yillar
    .map(([yil, s]) => `${yil}: ~${s.toLocaleString("tr-TR")}.`)
    .join("\n");

  return (
    <svg
      viewBox={`0 0 ${W} ${H}`}
      className="inline-block h-[18px] w-14 text-slate-300"
      role="img"
      aria-label={`Taban sıra geçmişi. ${ozet.replaceAll("\n", " ")}`}
    >
      <title>{ozet}</title>
      <polyline
        points={noktalar.map((n) => `${n.x},${n.y}`).join(" ")}
        fill="none"
        stroke="currentColor"
        strokeWidth="1.5"
        strokeLinecap="round"
        strokeLinejoin="round"
      />
      <circle cx={son.x} cy={son.y} r="2" className="fill-slate-500" />
    </svg>
  );
}

// Taban sıra iki yıl üst üste %10'dan fazla oynadıysa yönünü gösterir;
// küçük sıra = daha rekabetçi taban demektir.
function TabanTrendi({ p }: { p: Program }) {
  if (p.sira2025 == null || p.sira2024 == null) return null;
  const oran = (p.sira2024 - p.sira2025) / p.sira2024;
  if (Math.abs(oran) < 0.1) return null;
  const yukseliyor = oran > 0;
  const gecis = `${p.sira2024.toLocaleString("tr-TR")} → ${p.sira2025.toLocaleString("tr-TR")}`;
  return yukseliyor ? (
    <TrendingUp
      className="size-3 shrink-0 text-amber-500"
      aria-label={`Taban yükseliyor: ${gecis}`}
      role="img"
    >
      <title>{`Taban yükseliyor: ${gecis}`}</title>
    </TrendingUp>
  ) : (
    <TrendingDown
      className="size-3 shrink-0 text-emerald-600"
      aria-label={`Taban geriliyor: ${gecis}`}
      role="img"
    >
      <title>{`Taban geriliyor: ${gecis}`}</title>
    </TrendingDown>
  );
}

function ProgramSatiri({
  program: p,
  adaySira,
  listede,
  doldu,
  onEkle,
}: {
  program: Program;
  adaySira: number;
  listede: boolean;
  doldu: boolean;
  onEkle: (p: Program) => void;
}) {
  const taban = efektifSira(p);
  const risk = riskHesapla(taban, adaySira);
  const devlet = p.unitur === "DEVLET";

  return (
    <TableRow>
      <TableCell className="pl-4 pr-0">
        {risk ? (
          <span
            className={`block size-2.5 rounded-full ${RISK_NOKTA[risk]}`}
            aria-hidden
          />
        ) : null}
      </TableCell>
      <TableCell className="max-w-0 w-full">
        <span className="block truncate text-sm font-semibold">{p.isim}</span>
        <span className="mt-0.5 flex items-center gap-1.5 text-xs text-slate-500">
          <span
            className={`shrink-0 rounded px-1 py-px text-[10px] font-medium leading-4 ${
              devlet
                ? "bg-slate-100 text-slate-600"
                : "bg-violet-50 text-violet-600"
            }`}
          >
            {devlet ? "Devlet" : "Vakıf"}
          </span>
          <span className="truncate">
            {p.universite}
            {p.il ? ` · ${p.il.toLocaleLowerCase("tr-TR")}` : ""}
          </span>
          {p.sure ? (
            <span className="shrink-0 text-slate-400">· {p.sure} yıl</span>
          ) : null}
        </span>
      </TableCell>
      <TableCell className="hidden text-right text-xs md:table-cell">
        <SiraGecmisi p={p} />
      </TableCell>
      <TableCell
        className="hidden text-right text-xs tabular-nums text-slate-500 sm:table-cell"
        title={
          p.kontenjan2025 != null && p.yerlesen2025 != null
            ? `${p.kontenjan2025} kontenjan, ${p.yerlesen2025} yerleşen`
            : undefined
        }
      >
        {p.kontenjan2025 != null ? (
          <span className="inline-flex items-center gap-1.5">
            {p.yerlesen2025 != null && p.yerlesen2025 < p.kontenjan2025 ? (
              <span className="rounded bg-amber-50 px-1 py-px text-[10px] font-medium leading-4 text-amber-600">
                boş kaldı
              </span>
            ) : null}
            {p.kontenjan2025.toLocaleString("tr-TR")} kişi
          </span>
        ) : (
          "—"
        )}
      </TableCell>
      <TableCell className="text-right text-xs tabular-nums text-slate-500">
        <span className="inline-flex items-center gap-1">
          <TabanTrendi p={p} />
          {taban != null ? `~${taban.toLocaleString("tr-TR")}.` : "—"}
        </span>
      </TableCell>
      <TableCell className="pr-4 text-right">
        <button
          type="button"
          disabled={listede || doldu}
          onClick={() => onEkle(p)}
          title={
            listede
              ? "Zaten seçtiklerinde"
              : doldu
                ? `Seçtiklerin dolu (${MANUEL_LISTE_MAX}/${MANUEL_LISTE_MAX})`
                : "Seçtiklerime ekle"
          }
          className={`inline-flex size-8 cursor-pointer items-center justify-center rounded-full border transition-[background-color,border-color,color,transform] duration-150 active:scale-[0.92] disabled:cursor-default ${
            listede
              ? "border-emerald-200 bg-emerald-50 text-emerald-600"
              : "border-slate-200 bg-white text-slate-500 hover:border-primary hover:bg-primary/5 hover:text-primary disabled:opacity-40"
          }`}
        >
          {listede ? (
            <Check className="size-4" aria-hidden />
          ) : (
            <Plus className="size-4" aria-hidden />
          )}
          <span className="sr-only">
            {listede
              ? `${p.isim} seçtiklerinde`
              : `${p.isim} seçtiklerine ekle`}
          </span>
        </button>
      </TableCell>
    </TableRow>
  );
}
