"use client";

import { useEffect, useRef, useState } from "react";
import Link from "next/link";
import {
  ArrowRight,
  BookOpenText,
  Building2,
  GraduationCap,
  Search,
  X,
} from "lucide-react";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogTitle,
} from "@/components/ui/dialog";

type BolumSonucu = {
  href: string;
  ad: string;
  programSayisi: number;
  enIyiSira: number | null;
  seviye: string;
};

type UniversiteSonucu = {
  href: string;
  ad: string;
  il: string | null;
  tur: string | null;
  programSayisi: number;
  fakulteSayisi: number;
};

type AramaSonuclari = {
  bolumler: BolumSonucu[];
  universiteler: UniversiteSonucu[];
};

const BOS_SONUCLAR: AramaSonuclari = { bolumler: [], universiteler: [] };
const sayi = (deger: number) => deger.toLocaleString("tr-TR");

export function KatalogArama() {
  const [acik, setAcik] = useState(false);
  const [sorgu, setSorgu] = useState("");
  const [sonuclar, setSonuclar] = useState<AramaSonuclari>(BOS_SONUCLAR);
  const [yukleniyor, setYukleniyor] = useState(false);
  const inputRef = useRef<HTMLInputElement>(null);
  const temizSorgu = sorgu.trim();
  const aramaAktif = temizSorgu.length >= 2;
  const sonucVar =
    sonuclar.bolumler.length > 0 || sonuclar.universiteler.length > 0;

  useEffect(() => {
    if (!acik || !aramaAktif) return;

    const controller = new AbortController();
    const zamanlayici = window.setTimeout(async () => {
      setYukleniyor(true);
      try {
        const response = await fetch(
          `/api/katalog-ara?q=${encodeURIComponent(temizSorgu)}`,
          { signal: controller.signal },
        );
        if (!response.ok) throw new Error("Arama başarısız");
        setSonuclar((await response.json()) as AramaSonuclari);
      } catch (hata) {
        if (!(hata instanceof DOMException && hata.name === "AbortError")) {
          setSonuclar(BOS_SONUCLAR);
        }
      } finally {
        if (!controller.signal.aborted) setYukleniyor(false);
      }
    }, 160);

    return () => {
      window.clearTimeout(zamanlayici);
      controller.abort();
    };
  }, [acik, aramaAktif, temizSorgu]);

  function modalDegisti(yeniAcik: boolean) {
    setAcik(yeniAcik);
    if (!yeniAcik) {
      setSorgu("");
      setSonuclar(BOS_SONUCLAR);
    }
  }

  function kapat() {
    setAcik(false);
  }

  return (
    <>
      <nav className="absolute left-1/2 hidden -translate-x-1/2 items-center gap-1 rounded-full border border-slate-200 bg-white p-1.5 text-base font-medium text-slate-600 sm:flex">
        <Link
          href="/#nasil-calisir"
          className="rounded-full px-5 py-2 transition-colors duration-200 hover:bg-slate-100 hover:text-slate-900"
        >
          Nasıl çalışır?
        </Link>
        <Link
          href="/#karsilastirma"
          className="rounded-full px-5 py-2 transition-colors duration-200 hover:bg-slate-100 hover:text-slate-900"
        >
          Karşılaştır
        </Link>
        <button
          type="button"
          onClick={() => setAcik(true)}
          className="flex cursor-pointer items-center gap-2 rounded-full bg-slate-900 px-5 py-2 text-white transition-[background-color,transform] duration-150 hover:bg-slate-700 active:scale-[0.97]"
        >
          <Search className="size-4" aria-hidden />
          Ara
        </button>
      </nav>

      <button
        type="button"
        onClick={() => setAcik(true)}
        aria-label="Bölüm veya üniversite ara"
        className="ml-auto flex size-9 shrink-0 cursor-pointer items-center justify-center rounded-full border border-slate-200 bg-white text-slate-700 transition-[background-color,transform] duration-150 hover:bg-slate-100 active:scale-[0.96] sm:hidden"
      >
        <Search className="size-4" aria-hidden />
      </button>

      <Dialog open={acik} onOpenChange={modalDegisti}>
        <DialogContent
          showCloseButton={false}
          onOpenAutoFocus={(event) => {
            event.preventDefault();
            inputRef.current?.focus();
          }}
          className="max-h-[min(720px,calc(100dvh-2rem))] gap-0 overflow-hidden rounded-2xl bg-white p-0 duration-200 sm:max-w-2xl motion-reduce:data-open:zoom-in-100 motion-reduce:data-closed:zoom-out-100"
        >
          <DialogTitle className="sr-only">
            Bölüm ve üniversite ara
          </DialogTitle>
          <DialogDescription className="sr-only">
            YKS bölümlerini ve üniversiteleri tek yerden ara.
          </DialogDescription>

          <div className="flex items-center border-b border-slate-200 px-4 sm:px-5">
            <Search
              className="mr-3 size-5 shrink-0 text-slate-400"
              aria-hidden
            />
            <input
              ref={inputRef}
              type="text"
              value={sorgu}
              onChange={(event) => {
                const yeniSorgu = event.target.value;
                setSorgu(yeniSorgu);
                setSonuclar(BOS_SONUCLAR);
                setYukleniyor(yeniSorgu.trim().length >= 2);
              }}
              placeholder="Bölüm veya üniversite ara..."
              aria-label="Bölüm veya üniversite ara"
              autoComplete="off"
              className="h-16 min-w-0 flex-1 bg-transparent text-base text-slate-950 outline-none placeholder:text-slate-400 sm:h-18 sm:text-lg"
            />
            <button
              type="button"
              onClick={kapat}
              aria-label="Aramayı kapat"
              className="flex size-9 cursor-pointer items-center justify-center rounded-full border border-slate-200 text-slate-500 transition-[background-color,transform] duration-150 hover:bg-slate-100 hover:text-slate-800 active:scale-[0.96]"
            >
              <X className="size-4" aria-hidden />
            </button>
          </div>

          <div
            className="min-h-72 overflow-y-auto overscroll-contain p-3 sm:p-4"
            aria-live="polite"
          >
            {!aramaAktif ? (
              <BaslangicIcerigi onSec={kapat} />
            ) : yukleniyor ? (
              <AramaIskeleti />
            ) : sonucVar ? (
              <div className="space-y-5">
                {sonuclar.bolumler.length > 0 ? (
                  <SonucGrubu
                    baslik="Bölümler"
                    ikon={<GraduationCap className="size-4" aria-hidden />}
                  >
                    {sonuclar.bolumler.map((bolum) => (
                      <SonucLinki
                        key={bolum.href}
                        href={bolum.href}
                        baslik={bolum.ad}
                        meta={`${bolum.seviye} · ${sayi(bolum.programSayisi)} program`}
                        detay={
                          bolum.enIyiSira
                            ? `En iyi sıra ${sayi(bolum.enIyiSira)}`
                            : "Sıralama verisi yok"
                        }
                        onSec={kapat}
                      />
                    ))}
                  </SonucGrubu>
                ) : null}

                {sonuclar.universiteler.length > 0 ? (
                  <SonucGrubu
                    baslik="Üniversiteler"
                    ikon={<Building2 className="size-4" aria-hidden />}
                  >
                    {sonuclar.universiteler.map((universite) => (
                      <SonucLinki
                        key={universite.href}
                        href={universite.href}
                        baslik={universite.ad}
                        meta={
                          [universite.il, universite.tur]
                            .filter(Boolean)
                            .join(" · ") || "Üniversite"
                        }
                        detay={`${sayi(universite.programSayisi)} program · ${sayi(universite.fakulteSayisi)} fakülte`}
                        onSec={kapat}
                      />
                    ))}
                  </SonucGrubu>
                ) : null}
              </div>
            ) : (
              <div className="flex min-h-64 flex-col items-center justify-center px-6 text-center">
                <div className="flex size-12 items-center justify-center rounded-2xl bg-slate-100 text-slate-500">
                  <Search className="size-5" aria-hidden />
                </div>
                <p className="mt-4 font-medium text-slate-900">
                  &quot;{temizSorgu}&quot; için sonuç bulunamadı
                </p>
                <p className="mt-1 max-w-sm text-sm leading-6 text-slate-500">
                  Bölüm veya üniversite adını farklı yazarak tekrar dene.
                </p>
              </div>
            )}
          </div>

          <div className="flex items-center justify-between border-t border-slate-200 bg-slate-50/80 px-4 py-3 text-xs text-slate-500 sm:px-5">
            <span>En az 2 harf yazarak ara</span>
            <span className="hidden sm:inline">Esc ile kapat</span>
          </div>
        </DialogContent>
      </Dialog>
    </>
  );
}

function BaslangicIcerigi({ onSec }: { onSec: () => void }) {
  return (
    <div>
      <p className="px-2 pb-2 text-xs font-semibold uppercase tracking-wider text-slate-400">
        Keşfet
      </p>
      <div className="grid gap-2 sm:grid-cols-3">
        <KesfetLinki
          href="/bolumler"
          ikon={<GraduationCap className="size-5" aria-hidden />}
          baslik="Tüm bölümler"
          aciklama="Lisans ve önlisans"
          onSec={onSec}
        />
        <KesfetLinki
          href="/universiteler"
          ikon={<Building2 className="size-5" aria-hidden />}
          baslik="Üniversiteler"
          aciklama="Devlet ve vakıf"
          onSec={onSec}
        />
        <KesfetLinki
          href="/rehber"
          ikon={<BookOpenText className="size-5" aria-hidden />}
          baslik="Tercih rehberi"
          aciklama="Sorularına yanıtlar"
          onSec={onSec}
        />
      </div>
      <div className="mt-6 rounded-xl border border-orange-100 bg-orange-50/70 p-4">
        <p className="text-sm font-medium text-slate-900">
          Neyi merak ediyorsun?
        </p>
        <p className="mt-1 text-sm leading-6 text-slate-600">
          “Psikoloji” veya “Boğaziçi” gibi bir ad yaz; eşleşen sayfaları ve
          temel bilgilerini burada önizle.
        </p>
      </div>
    </div>
  );
}

function KesfetLinki({
  href,
  ikon,
  baslik,
  aciklama,
  onSec,
}: {
  href: string;
  ikon: React.ReactNode;
  baslik: string;
  aciklama: string;
  onSec: () => void;
}) {
  return (
    <Link
      href={href}
      onClick={onSec}
      className="group rounded-xl border border-slate-200 bg-white p-4 transition-[border-color,background-color,transform] duration-150 hover:border-slate-300 hover:bg-slate-50 active:scale-[0.98]"
    >
      <span className="flex size-9 items-center justify-center rounded-lg bg-slate-100 text-slate-600 transition-colors group-hover:bg-white">
        {ikon}
      </span>
      <span className="mt-3 block text-sm font-semibold text-slate-900">
        {baslik}
      </span>
      <span className="mt-0.5 block text-xs text-slate-500">{aciklama}</span>
    </Link>
  );
}

function SonucGrubu({
  baslik,
  ikon,
  children,
}: {
  baslik: string;
  ikon: React.ReactNode;
  children: React.ReactNode;
}) {
  return (
    <section>
      <h3 className="mb-2 flex items-center gap-2 px-2 text-xs font-semibold uppercase tracking-wider text-slate-400">
        {ikon}
        {baslik}
      </h3>
      <div className="space-y-1">{children}</div>
    </section>
  );
}

function SonucLinki({
  href,
  baslik,
  meta,
  detay,
  onSec,
}: {
  href: string;
  baslik: string;
  meta: string;
  detay: string;
  onSec: () => void;
}) {
  return (
    <Link
      href={href}
      onClick={onSec}
      className="group flex items-center gap-3 rounded-xl px-3 py-3 transition-colors duration-150 hover:bg-slate-100"
    >
      <span className="min-w-0 flex-1">
        <span className="block truncate text-sm font-semibold text-slate-900">
          {baslik}
        </span>
        <span className="mt-1 block truncate text-xs text-slate-500">
          {meta}
        </span>
      </span>
      <span className="hidden shrink-0 text-right text-xs text-slate-400 sm:block">
        {detay}
      </span>
      <ArrowRight
        className="size-4 shrink-0 text-slate-300 transition-[color,transform] duration-150 group-hover:translate-x-0.5 group-hover:text-slate-600"
        aria-hidden
      />
    </Link>
  );
}

function AramaIskeleti() {
  return (
    <div className="space-y-2 px-2 pt-2" aria-label="Aranıyor">
      {[0, 1, 2, 3].map((sira) => (
        <div
          key={sira}
          className="flex h-16 animate-pulse items-center rounded-xl bg-slate-100 px-3 motion-reduce:animate-none"
        >
          <div className="h-4 w-2/5 rounded bg-slate-200" />
        </div>
      ))}
    </div>
  );
}
