"use client";
import Link from "next/link";
import { useEffect, useMemo, useRef, useState } from "react";
import { Search, X } from "lucide-react";

import { api } from "@/lib/api";
import type { Genre, ServiceType } from "@/lib/types";
import { cn } from "@/lib/utils";

type Tab = "tipos" | "generos";
type Row = { slug: string; name: string; emoji?: string };

const ABC = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".split("");

/** Quita tildes para que "saxofón" aparezca al escribir "saxofon" y agrupe bajo la S. */
const norm = (s: string) => s.normalize("NFD").replace(/\p{Diacritic}/gu, "").toLowerCase();

function letterOf(name: string) {
  const c = norm(name)[0] ?? "#";
  return /[a-z]/.test(c) ? c.toUpperCase() : "#";
}

export function CatalogDrawer({ open, onClose }: { open: boolean; onClose: () => void }) {
  const [tab, setTab] = useState<Tab>("tipos");
  const [q, setQ] = useState("");
  const [types, setTypes] = useState<ServiceType[]>([]);
  const [genres, setGenres] = useState<Genre[]>([]);
  const inputRef = useRef<HTMLInputElement>(null);
  const listRef = useRef<HTMLDivElement>(null);

  // El catálogo es estático en el backend: se pide una vez y se reusa mientras dure la visita.
  useEffect(() => {
    if (!open || types.length) return;
    api.serviceTypes().then(setTypes).catch(() => setTypes([]));
    api.genres().then(setGenres).catch(() => setGenres([]));
  }, [open, types.length]);

  useEffect(() => {
    if (!open) return;
    const onKey = (e: KeyboardEvent) => e.key === "Escape" && onClose();
    document.addEventListener("keydown", onKey);
    document.body.style.overflow = "hidden";
    const t = setTimeout(() => inputRef.current?.focus(), 340);
    return () => {
      document.removeEventListener("keydown", onKey);
      document.body.style.overflow = "";
      clearTimeout(t);
    };
  }, [open, onClose]);

  const rows: Row[] = tab === "tipos" ? types : genres;

  const buckets = useMemo(() => {
    const term = norm(q.trim());
    const out: Record<string, Row[]> = {};
    rows
      .filter((r) => !term || norm(r.name).includes(term))
      .forEach((r) => {
        const L = letterOf(r.name);
        (out[L] ||= []).push(r);
      });
    return out;
  }, [rows, q]);

  const letters = Object.keys(buckets).sort();
  const hrefFor = (slug: string) => (tab === "tipos" ? `/buscar?service=${slug}` : `/buscar?genre=${slug}`);

  const jump = (L: string) => {
    const el = listRef.current?.querySelector(`[data-letter="${L}"]`);
    el?.scrollIntoView({ behavior: "smooth", block: "start" });
  };

  return (
    <>
      <div
        onClick={onClose}
        className={cn(
          "fixed inset-0 z-[1200] bg-navy/60 backdrop-blur-sm transition-opacity duration-300",
          open ? "opacity-100" : "pointer-events-none opacity-0",
        )}
      />
      <aside
        role="dialog"
        aria-modal="true"
        aria-label="Catálogo completo"
        className={cn(
          "fixed z-[1300] flex flex-col bg-bg-card shadow-2xl transition-transform duration-500 ease-out",
          "inset-y-0 right-0 w-full max-w-[560px]",
          "max-sm:inset-x-0 max-sm:bottom-0 max-sm:top-auto max-sm:h-[88svh] max-sm:max-w-none max-sm:rounded-t-3xl",
          open ? "translate-x-0 max-sm:translate-y-0" : "translate-x-full max-sm:translate-x-0 max-sm:translate-y-full",
        )}
      >
        <div className="border-b border-line px-5 pb-4 pt-5">
          <div className="flex items-center justify-between gap-4">
            <h2 className="text-lg font-extrabold tracking-tight">Catálogo completo</h2>
            <button
              onClick={onClose}
              aria-label="Cerrar"
              className="grid h-9 w-9 place-items-center rounded-lg border border-line text-ink-mute transition hover:border-ink-mute hover:text-ink"
            >
              <X size={17} />
            </button>
          </div>

          <div className="mt-4 inline-flex gap-1 rounded-xl border border-line bg-bg-soft p-1">
            {([["tipos", "Tipos", types.length], ["generos", "Géneros", genres.length]] as const).map(
              ([key, label, n]) => (
                <button
                  key={key}
                  role="tab"
                  aria-selected={tab === key}
                  onClick={() => {
                    setTab(key);
                    setQ("");
                    if (listRef.current) listRef.current.scrollTop = 0;
                  }}
                  className={cn(
                    "rounded-lg px-4 py-1.5 text-sm font-semibold transition",
                    tab === key ? "bg-bg-card text-ink shadow-soft" : "text-ink-mute hover:text-ink",
                  )}
                >
                  {label} {n > 0 && <span className="font-mono text-xs text-ink-mute">{n}</span>}
                </button>
              ),
            )}
          </div>

          <label className="mt-3 flex items-center gap-2 rounded-xl border border-line px-3 py-2.5 transition focus-within:border-accent focus-within:ring-2 focus-within:ring-accent/20">
            <Search size={15} className="shrink-0 text-ink-mute" />
            <input
              ref={inputRef}
              value={q}
              onChange={(e) => setQ(e.target.value)}
              placeholder="Buscar saxofón, salsa, mariachi…"
              className="min-w-0 flex-1 bg-transparent text-sm outline-none placeholder:text-ink-mute"
            />
          </label>
        </div>

        <div className="flex min-h-0 flex-1">
          <div ref={listRef} className="flex-1 overflow-y-auto pb-10">
            {letters.length === 0 ? (
              <p className="px-5 py-12 text-center text-sm leading-relaxed text-ink-mute">
                Nada con “{q.trim()}”.
                <br />
                Probá otro nombre — o escribí tu género libre al crear el perfil.
              </p>
            ) : (
              letters.map((L) => (
                <section key={L} data-letter={L}>
                  <div className="sticky top-0 z-10 border-b border-line bg-bg-card/95 px-5 py-1.5 font-mono text-xs font-bold tracking-widest text-accent-deep backdrop-blur">
                    {L}
                  </div>
                  {buckets[L].map((r) => (
                    <Link
                      key={r.slug}
                      href={hrefFor(r.slug)}
                      onClick={onClose}
                      className="group flex w-full items-center gap-3 px-5 py-2.5 text-sm transition hover:bg-bg-soft"
                    >
                      <span className="w-6 shrink-0 text-center text-lg">{r.emoji ?? "♪"}</span>
                      <span>{r.name}</span>
                      <span className="ml-auto font-mono text-[11px] text-ink-mute opacity-0 transition group-hover:opacity-100">
                        buscar →
                      </span>
                    </Link>
                  ))}
                </section>
              ))
            )}
          </div>

          <nav
            aria-label="Índice alfabético"
            className="flex w-9 shrink-0 flex-col items-center gap-px overflow-y-auto border-l border-line bg-bg-soft py-2"
          >
            {ABC.map((L) => (
              <button
                key={L}
                disabled={!buckets[L]}
                onClick={() => jump(L)}
                className="h-[19px] w-[22px] rounded font-mono text-[11px] font-bold text-ink-mute transition enabled:hover:bg-accent enabled:hover:text-white disabled:text-line"
              >
                {L}
              </button>
            ))}
          </nav>
        </div>
      </aside>
    </>
  );
}
