// routes/_authenticated/asignatura/$asignaturaId.tsx
import { createFileRoute, Link, useRouter } from "@tanstack/react-router"
import * as Icons from "lucide-react"
import { useEffect, useMemo, useRef, useState } from "react"
import { supabase } from "@/auth/supabase"
import { Button } from "@/components/ui/button"
import { Badge } from "@/components/ui/badge"
import { Input } from "@/components/ui/input"
import {
  Accordion, AccordionContent, AccordionItem, AccordionTrigger,
} from "@/components/ui/accordion"

/* ================== Tipos ================== */
type Asignatura = {
  id: string; nombre: string; clave: string | null; tipo: string | null; semestre: number | null;
  creditos: number | null; horas_teoricas: number | null; horas_practicas: number | null;
  objetivos: string | null; contenidos: Record<string, Record<string, string>> | null;
  bibliografia: string[] | null; criterios_evaluacion: string | null; plan_id: string | null;
}
type PlanMini = { id: string; nombre: string }

/* ================== Ruta ================== */
export const Route = createFileRoute("/_authenticated/asignatura/$asignaturaId")({
  component: Page,
  loader: async ({ params }) => {
    const { data: a, error } = await supabase
      .from("asignaturas")
      .select("id, nombre, clave, tipo, semestre, creditos, horas_teoricas, horas_practicas, objetivos, contenidos, bibliografia, criterios_evaluacion, plan_id")
      .eq("id", params.asignaturaId)
      .single()
    if (error || !a) throw error ?? new Error("Asignatura no encontrada")

    let plan: PlanMini | null = null
    if (a.plan_id) {
      const { data: p } = await supabase
        .from("plan_estudios").select("id, nombre").eq("id", a.plan_id).single()
      plan = p as PlanMini | null
    }
    return { a: a as Asignatura, plan }
  },
})

/* ================== Helpers UI ================== */
function typeStyle(tipo?: string | null) {
  const t = (tipo ?? "").toLowerCase()
  if (t.includes("oblig")) return { chip: "bg-emerald-50 text-emerald-700 border-emerald-200", halo: "from-emerald-100/60" }
  if (t.includes("opt"))    return { chip: "bg-amber-50 text-amber-800 border-amber-200", halo: "from-amber-100/60" }
  if (t.includes("taller")) return { chip: "bg-indigo-50 text-indigo-700 border-indigo-200", halo: "from-indigo-100/60" }
  if (t.includes("lab"))    return { chip: "bg-sky-50 text-sky-700 border-sky-200", halo: "from-sky-100/60" }
  return { chip: "bg-neutral-100 text-neutral-700 border-neutral-200", halo: "from-primary/10" }
}

function Stat({ icon: Icon, label, value }:{
  icon: any; label: string; value: string | number
}) {
  return (
    <div className="rounded-2xl border bg-white/70 dark:bg-neutral-900/60 p-3 flex items-center gap-3">
      <div className="h-9 w-9 rounded-xl grid place-items-center border bg-white/80">
        <Icon className="h-4 w-4" />
      </div>
      <div>
        <div className="text-xs text-neutral-500">{label}</div>
        <div className="text-lg font-semibold tabular-nums">{value}</div>
      </div>
    </div>
  )
}

function Section({ id, title, icon: Icon, children }:{
  id: string; title: string; icon: any; children: React.ReactNode
}) {
  return (
    <section id={id} className="rounded-2xl border bg-white/70 dark:bg-neutral-900/60 p-4 scroll-mt-24">
      <header className="flex items-center gap-2 mb-2">
        <div className="h-8 w-8 rounded-lg grid place-items-center border bg-white/80"><Icon className="h-4 w-4" /></div>
        <h3 className="text-sm font-semibold">{title}</h3>
      </header>
      {children}
    </section>
  )
}

/* ================== Página ================== */
function Page() {
  const router = useRouter()
  const { a, plan } = Route.useLoaderData() as { a: Asignatura; plan: PlanMini | null }
  const horasT = a.horas_teoricas ?? 0
  const horasP = a.horas_practicas ?? 0
  const horas = horasT + horasP
  const style = typeStyle(a.tipo)

  // ordenar unidades de forma “natural”
  const unidades = useMemo(() => {
    const entries = Object.entries(a.contenidos ?? {})
    const norm = (s: string) => {
      const m = String(s).match(/^\s*(\d+)/)
      return m ? [parseInt(m[1], 10), s] as const : [Number.POSITIVE_INFINITY, s] as const
    }
    return entries
      .map(([k, v]) => ({ key: k, order: norm(k)[0], title: norm(k)[1], temas: Object.entries(v) }))
      .sort((A, B) => (A.order === B.order ? A.title.localeCompare(B.title) : A.order - B.order))
      .map(u => ({ ...u, temas: u.temas.sort(([a],[b]) => Number(a) - Number(b)) }))
  }, [a.contenidos])

  const temasCount = useMemo(() => unidades.reduce((acc, u) => acc + u.temas.length, 0), [unidades])

  // buscar dentro del syllabus
  const [query, setQuery] = useState("")
  const filteredUnidades = useMemo(() => {
    const t = query.trim().toLowerCase()
    if (!t) return unidades
    return unidades.map(u => ({
      ...u,
      temas: u.temas.filter(([, tema]) => String(tema).toLowerCase().includes(t)),
    })).filter(u => u.temas.length > 0)
  }, [query, unidades])

  // atajos y compartir
  const searchRef = useRef<HTMLInputElement | null>(null)
  useEffect(() => {
    const onKey = (e: KeyboardEvent) => {
      if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === "k") { e.preventDefault(); searchRef.current?.focus() }
      if (e.key === "Escape") router.history.back()
    }
    window.addEventListener("keydown", onKey)
    return () => window.removeEventListener("keydown", onKey)
  }, [router])

  async function share() {
    const url = window.location.href
    try {
      if (navigator.share) await navigator.share({ title: a.nombre, url })
      else {
        await navigator.clipboard.writeText(url)
        // feedback visual mínimo
        alert("Enlace copiado")
      }
    } catch { /* noop */ }
  }

  return (
    <div className="relative p-6 space-y-6">
      {/* ===== Migas ===== */}
      <nav className="text-sm text-neutral-500">
        <Link
          to={plan ? "/plan/$planId" : "/planes"}
          params={plan ? { planId: plan.id } : undefined}
          className="hover:underline"
        >
          {plan ? plan.nombre : "Planes"}
        </Link>
        <span className="mx-1">/</span>
        <span className="text-neutral-900">{a.nombre}</span>
      </nav>

      {/* ===== Hero ===== */}
      <div className="relative overflow-hidden rounded-3xl border shadow-sm">
        <div className={`absolute inset-0 bg-gradient-to-br ${style.halo} via-white to-transparent`} />
        <div className="relative p-6 flex flex-col gap-4 md:flex-row md:items-center md:justify-between">
          <div className="min-w-0">
            <div className="inline-flex items-center gap-2 text-xs text-neutral-600">
              <Icons.BookOpen className="h-4 w-4" /> Asignatura
              {plan && <>
                <span>·</span>
                <Link to="/plan/$planId" params={{ planId: plan.id }} className="hover:underline">
                  {plan.nombre}
                </Link>
              </>}
            </div>
            <h1 className="mt-1 text-2xl md:text-3xl font-bold truncate">{a.nombre}</h1>
            <div className="mt-2 flex flex-wrap items-center gap-2 text-[11px]">
              {a.clave && <Badge variant="outline">Clave: {a.clave}</Badge>}
              {a.tipo   && <Badge className={style.chip} variant="secondary">{a.tipo}</Badge>}
              {a.creditos != null && <Badge variant="outline">{a.creditos} créditos</Badge>}
              <Badge variant="outline">H T/P: {horasT}/{horasP}</Badge>
              <Badge variant="outline">Semestre {a.semestre ?? "—"}</Badge>
            </div>
          </div>

          {/* Acciones rápidas */}
          <div className="flex items-center gap-2">
            <Button variant="outline" size="sm" onClick={() => window.print()}>
              <Icons.Printer className="h-4 w-4 mr-2" /> Imprimir
            </Button>
            <Button variant="outline" size="sm" onClick={share}>
              <Icons.Share2 className="h-4 w-4 mr-2" /> Compartir
            </Button>
          </div>
        </div>

        {/* Stats rápidos */}
        <div className="relative px-6 pb-6">
          <div className="grid gap-3 sm:grid-cols-2 lg:grid-cols-4">
            <Stat icon={Icons.Coins} label="Créditos" value={a.creditos ?? "—"} />
            <Stat icon={Icons.Clock} label="Horas totales" value={horas} />
            <Stat icon={Icons.ListTree} label="Unidades" value={unidades.length} />
            <Stat icon={Icons.BookMarked} label="Temas" value={temasCount} />
          </div>
        </div>
      </div>

      {/* ===== Layout principal ===== */}
      <div className="grid gap-6 lg:grid-cols-[1fr,320px]">
        {/* ===== Columna principal ===== */}
        <div className="space-y-6">
          {/* Objetivo */}
          {a.objetivos && (
            <Section id="objetivo" title="Objetivo de la asignatura" icon={Icons.Target}>
              <p className="text-sm leading-relaxed text-neutral-800">{a.objetivos}</p>
            </Section>
          )}

          {/* Syllabus */}
          {unidades.length > 0 && (
            <Section id="syllabus" title="Programa / Contenidos" icon={Icons.ListTree}>
              <div className="flex items-center gap-2 mb-2">
                <div className="relative flex-1">
                  <Icons.Search className="absolute left-2 top-1/2 -translate-y-1/2 h-4 w-4 text-neutral-400" />
                  <Input
                    ref={searchRef}
                    value={query}
                    onChange={(e) => setQuery(e.target.value)}
                    placeholder="Buscar tema dentro del programa (⌘/Ctrl K)…"
                    className="pl-8"
                  />
                </div>
                {query && (
                  <Button variant="ghost" onClick={() => setQuery("")}>
                    Limpiar
                  </Button>
                )}
              </div>

              <Accordion type="multiple" className="mt-2">
                {filteredUnidades.map((u, i) => (
                  <AccordionItem key={u.key} value={`u-${i}`} className="border rounded-xl mb-2 overflow-hidden">
                    <AccordionTrigger className="px-4 py-2 hover:no-underline text-left">
                      <div className="flex items-center justify-between w-full">
                        <span className="font-medium">
                          {/^\s*\d+/.test(u.key) ? `Unidad ${u.key}` : u.title}
                        </span>
                        <span className="text-[11px] text-neutral-500">{u.temas.length} tema(s)</span>
                      </div>
                    </AccordionTrigger>
                    <AccordionContent className="px-5 pb-3">
                      <ul className="list-disc ml-5 text-[13px] text-neutral-700 space-y-1">
                        {u.temas.map(([k, t]) => <li key={k} className="break-words">{t}</li>)}
                      </ul>
                    </AccordionContent>
                  </AccordionItem>
                ))}
                {filteredUnidades.length === 0 && (
                  <div className="text-sm text-neutral-500 py-6 text-center">No hay temas que coincidan.</div>
                )}
              </Accordion>
            </Section>
          )}

          {/* Bibliografía */}
          {a.bibliografia && a.bibliografia.length > 0 && (
            <Section id="bibliografia" title="Bibliografía" icon={Icons.LibraryBig}>
              <ul className="space-y-2 text-sm text-neutral-800">
                {a.bibliografia.map((ref, i) => (
                  <li key={i} className="flex items-start gap-2 leading-relaxed">
                    <span className="mt-1 text-neutral-400">•</span>
                    <span className="break-words">{ref}</span>
                  </li>
                ))}
              </ul>
            </Section>
          )}

          {/* Evaluación */}
          {a.criterios_evaluacion && (
            <Section id="evaluacion" title="Criterios de evaluación" icon={Icons.ClipboardCheck}>
              <p className="text-sm text-neutral-800 leading-relaxed">{a.criterios_evaluacion}</p>
            </Section>
          )}
        </div>

        {/* ===== Sidebar ===== */}
        <aside className="space-y-4 lg:sticky lg:top-6 self-start">
          <div className="rounded-2xl border bg-white/70 dark:bg-neutral-900/60 p-4">
            <h4 className="font-semibold text-sm mb-2">Resumen</h4>
            <div className="grid grid-cols-2 gap-2 text-xs">
              <MiniKV label="Créditos" value={a.creditos ?? "—"} />
              <MiniKV label="Semestre" value={a.semestre ?? "—"} />
              <MiniKV label="Horas teóricas" value={horasT} />
              <MiniKV label="Horas prácticas" value={horasP} />
              <MiniKV label="Unidades" value={unidades.length} />
              <MiniKV label="Temas" value={temasCount} />
            </div>
          </div>

          <div className="rounded-2xl border bg-white/70 dark:bg-neutral-900/60 p-4">
            <h4 className="font-semibold text-sm mb-2">Navegación</h4>
            <nav className="text-sm space-y-1">
              {a.objetivos && <Anchor href="#objetivo" label="Objetivo" />}
              {unidades.length > 0 && <Anchor href="#syllabus" label="Programa / Contenidos" />}
              {a.bibliografia && a.bibliografia.length > 0 && <Anchor href="#bibliografia" label="Bibliografía" />}
              {a.criterios_evaluacion && <Anchor href="#evaluacion" label="Evaluación" />}
            </nav>
          </div>

          {plan && (
            <Link
              to="/plan/$planId"
              params={{ planId: plan.id }}
              className="block rounded-2xl border p-4 hover:bg-neutral-50 transition"
            >
              <div className="flex items-center gap-3">
                <div className="h-9 w-9 rounded-xl grid place-items-center border bg-white/80">
                  <Icons.ScrollText className="h-4 w-4" />
                </div>
                <div>
                  <div className="text-xs text-neutral-500">Plan de estudios</div>
                  <div className="font-medium truncate">{plan.nombre}</div>
                </div>
              </div>
            </Link>
          )}
        </aside>
      </div>

      {/* ===== Volver ===== */}
      <div className="pt-2">
        <Button variant="outline" asChild>
          <Link to={plan ? "/plan/$planId" : "/planes"} params={plan ? { planId: plan.id } : undefined}>
            <Icons.ArrowLeft className="h-4 w-4 mr-2" /> Volver
          </Link>
        </Button>
      </div>
    </div>
  )
}

/* ===== Bits Sidebar ===== */
function MiniKV({ label, value }:{ label: string; value: string | number }) {
  return (
    <div className="rounded-xl border bg-white/60 p-2">
      <div className="text-[11px] text-neutral-500">{label}</div>
      <div className="font-medium tabular-nums">{value}</div>
    </div>
  )
}
function Anchor({ href, label }:{ href: string; label: string }) {
  return (
    <a href={href} className="flex items-center gap-2 text-neutral-700 hover:underline">
      <Icons.Dot className="h-5 w-5 -ml-1" /> {label}
    </a>
  )
}
