import { createFileRoute, Link, useRouter } from '@tanstack/react-router'
import { supabase, useSupabaseAuth } from '@/auth/supabase'
import * as Icons from 'lucide-react'
import { useMemo } from 'react'
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { Badge } from '@/components/ui/badge'

/* ========= Tipos ========= */
type Plan = {
  id: string
  nombre: string
  fecha_creacion: string | null
  objetivo_general: string | null
  perfil_ingreso: string | null
  perfil_egreso: string | null
  sistema_evaluacion: string | null
  total_creditos: number | null
}
type Asignatura = {
  id: string
  nombre: string
  fecha_creacion: string | null
  contenidos: any | null
  criterios_evaluacion: string | null
  bibliografia: any | null
}

type LoaderData = {
  kpis: { facultades: number; carreras: number; planes: number; asignaturas: number }
  calidadPlanesPct: number
  saludAsignaturas: { sinBibliografia: number; sinCriterios: number; sinContenidos: number }
  recientes: Array<{ tipo: 'plan' | 'asignatura'; id: string; nombre: string; fecha: string | null }>
}

/* ========= Loader ========= */
export const Route = createFileRoute('/_authenticated/dashboard')({
  component: RouteComponent,
  pendingComponent: DashboardSkeleton,
  loader: async (): Promise<LoaderData> => {
    // KPI counts
    const [{ count: facCount }, { count: carCount }, { data: planesRaw }, { data: asignRaw }] =
      await Promise.all([
        supabase.from('facultades').select('*', { count: 'exact', head: true }),
        supabase.from('carreras').select('*', { count: 'exact', head: true }),
        supabase
          .from('plan_estudios')
          .select(
            'id, nombre, fecha_creacion, objetivo_general, perfil_ingreso, perfil_egreso, sistema_evaluacion, total_creditos'
          ),
        supabase
          .from('asignaturas')
          .select('id, nombre, fecha_creacion, contenidos, criterios_evaluacion, bibliografia')
      ])

    const planes = (planesRaw ?? []) as Plan[]
    const asignaturas = (asignRaw ?? []) as Asignatura[]

    // Calidad de planes
    const needed: (keyof Plan)[] = [
      'objetivo_general',
      'perfil_ingreso',
      'perfil_egreso',
      'sistema_evaluacion',
      'total_creditos'
    ]
    const completos = planes.filter(p =>
      needed.every(k => p[k] !== null && String(p[k] ?? '').toString().trim() !== '')
    ).length
    const calidadPlanesPct = planes.length ? Math.round((completos / planes.length) * 100) : 0

    // Salud de asignaturas
    const sinBibliografia = asignaturas.filter(
      a => !a.bibliografia || (Array.isArray(a.bibliografia) && a.bibliografia.length === 0)
    ).length
    const sinCriterios = asignaturas.filter(a => !a.criterios_evaluacion?.trim()).length
    const sinContenidos = asignaturas.filter(
      a => !a.contenidos || (Array.isArray(a.contenidos) && a.contenidos.length === 0)
    ).length

    // Actividad reciente (últimos 8 ítems)
    const recientes = [
      ...planes.map(p => ({ tipo: 'plan' as const, id: p.id, nombre: p.nombre, fecha: p.fecha_creacion })),
      ...asignaturas.map(a => ({ tipo: 'asignatura' as const, id: a.id, nombre: a.nombre, fecha: a.fecha_creacion }))
    ]
      .sort((a, b) => new Date(b.fecha ?? 0).getTime() - new Date(a.fecha ?? 0).getTime())
      .slice(0, 8)

    return {
      kpis: {
        facultades: facCount ?? 0,
        carreras: carCount ?? 0,
        planes: planes.length,
        asignaturas: asignaturas.length
      },
      calidadPlanesPct,
      saludAsignaturas: { sinBibliografia, sinCriterios, sinContenidos },
      recientes
    }
  }
})

/* ========= Helpers visuales ========= */
function gradient(bg = '#2563eb') {
  return {
    background: `linear-gradient(135deg, ${bg} 0%, ${bg}cc 45%, ${bg}a6 75%, ${bg}66 100%)`
  } as React.CSSProperties
}
function hex(color?: string | null, fallback = '#2563eb') {
  return color && /^#([0-9a-f]{6}|[0-9a-f]{3})$/i.test(color) ? color : fallback
}
function Ring({ pct, color }: { pct: number; color: string }) {
  const R = 42
  const C = 2 * Math.PI * R
  const off = C * (1 - Math.min(Math.max(pct, 0), 100) / 100)
  return (
    <div className="flex items-center gap-4">
      <svg width="112" height="112" viewBox="0 0 112 112">
        <circle cx="56" cy="56" r={R} fill="none" stroke="#e5e7eb" strokeWidth="12" />
        <circle
          cx="56"
          cy="56"
          r={R}
          fill="none"
          stroke={color}
          strokeWidth="12"
          strokeDasharray={C}
          strokeDashoffset={off}
          strokeLinecap="round"
          transform="rotate(-90 56 56)"
        />
      </svg>
      <div>
        <div className="text-3xl font-bold tabular-nums">{pct}%</div>
        <div className="text-sm text-neutral-600">Planes con información clave completa</div>
      </div>
    </div>
  )
}

function Tile({
  to,
  label,
  value,
  Icon
}: {
  to: string
  label: string
  value: number | string
  Icon: React.ComponentType<React.SVGProps<SVGSVGElement>>
}) {
  return (
    <Link
      to={to}
      className="group rounded-2xl ring-1 ring-black/5 bg-white/80 dark:bg-neutral-900/60 p-5 flex items-center justify-between hover:-translate-y-0.5 transition-all"
    >
      <div>
        <div className="text-sm text-neutral-500">{label}</div>
        <div className="text-3xl font-bold tabular-nums">{value}</div>
      </div>
      <div className="p-3 rounded-xl bg-neutral-100 dark:bg-neutral-800 group-hover:bg-neutral-200">
        <Icon className="w-7 h-7" />
      </div>
    </Link>
  )
}

/* ========= Página ========= */
function RouteComponent() {
  const { kpis, calidadPlanesPct, saludAsignaturas, recientes } = Route.useLoaderData() as LoaderData
  const auth = useSupabaseAuth()
  const router = useRouter()
  const primary = hex(auth.claims?.facultad_color, '#1d4ed8') // si guardan color de facultad en claims

  const name = auth.user?.user_metadata?.nombre || auth.user?.email?.split('@')[0] || '¡Hola!'

  const isAdmin = !!auth.claims?.claims_admin
  const role = auth.claims?.role as
    | 'lci'
    | 'vicerrectoria'
    | 'secretario_academico'
    | 'jefe_carrera'
    | 'planeacion'
    | undefined

  // Mensaje contextual
  const roleHint = useMemo(() => {
    switch (role) {
      case 'vicerrectoria':
        return 'Panorama académico, calidad y actividad reciente.'
      case 'secretario_academico':
        return 'Enfócate en tu facultad: salud de asignaturas y avance de planes.'
      case 'jefe_carrera':
        return 'Accede rápido a planes y asignaturas de tu carrera.'
      case 'planeacion':
        return 'Monitorea consistencia de planes y evidencias de evaluación.'
      default:
        return 'Atajos para crear, revisar y mejorar contenido.'
    }
  }, [role])

  return (
    <div className="p-6 space-y-8">
      {/* Header con saludo y búsqueda global */}
      <div className="relative rounded-3xl overflow-hidden shadow-xl text-white" style={gradient(primary)}>
        <div
          className="absolute inset-0 opacity-25"
          style={{ background: 'radial-gradient(800px 300px at 20% -10%, #fff, transparent 60%)' }}
        />
        <div className="relative p-6 md:p-8 flex flex-col gap-5">
          <div className="flex flex-wrap items-center justify-between gap-3">
            <div className="min-w-0">
              <h1 className="text-2xl md:text-3xl font-bold leading-tight">Hola, {name}</h1>
              <p className="opacity-95">{roleHint}</p>
            </div>
            <div className="flex items-center gap-2">
              {role && <Badge variant="secondary" className="bg-white/20 text-white border-white/30">{role}</Badge>}
              {isAdmin && (
                <Badge className="bg-white/20 text-white border-white/30 flex items-center gap-1">
                  <Icons.ShieldCheck className="w-3.5 h-3.5" /> admin
                </Badge>
              )}
            </div>
          </div>

          <div className="flex items-center gap-2 w-full">
            <Input
              placeholder="Buscar planes, asignaturas o personas… (Enter)"
              className="bg-white/90 text-neutral-800 placeholder:text-neutral-400"
              onKeyDown={e => {
                if (e.key === 'Enter') {
                  const q = (e.target as HTMLInputElement).value.trim()
                  if (!q) return
                  router.navigate({ to: '/planes', search: { q } })
                }
              }}
            />
            <Button
              variant="secondary"
              className="bg-white/20 text-white hover:bg-white/30 border-white/30"
              onClick={() => router.invalidate()}
              title="Actualizar"
            >
              <Icons.RefreshCcw className="w-4 h-4" />
            </Button>
          </div>

          {/* Atajos rápidos (según rol) */}
          <div className="flex flex-wrap gap-2">
            <Link
              to="/planes"
              className="inline-flex items-center gap-2 rounded-xl bg-white/20 border border-white/30 px-3 py-1.5 text-sm hover:bg-white/30"
            >
              <Icons.ScrollText className="w-4 h-4" /> Nuevo plan
            </Link>
            <Link
              to="/asignaturas"
              search={{ carreraId: '', f: '', facultadId: '', planId: '', q: '' }}
              className="inline-flex items-center gap-2 rounded-xl bg-white/20 border border-white/30 px-3 py-1.5 text-sm hover:bg-white/30">
              <Icons.BookOpen className="w-4 h-4" /> Nueva asignatura
            </Link>
            {isAdmin && (
              <Link
                to="/usuarios"
                className="inline-flex items-center gap-2 rounded-xl bg-white/20 border border-white/30 px-3 py-1.5 text-sm hover:bg-white/30"
              >
                <Icons.UserPlus className="w-4 h-4" /> Invitar usuario
              </Link>
            )}
          </div>
        </div>
      </div>

      {/* KPIs principales */}
      <div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-4">
        <Tile to="/_authenticated/facultades" label="Facultades" value={kpis.facultades} Icon={Icons.Building2} />
        <Tile to="/_authenticated/carreras" label="Carreras" value={kpis.carreras} Icon={Icons.GraduationCap} />
        <Tile to="/_authenticated/planes" label="Planes de estudio" value={kpis.planes} Icon={Icons.ScrollText} />
        <Tile to="/_authenticated/asignaturas" label="Asignaturas" value={kpis.asignaturas} Icon={Icons.BookOpen} />
      </div>

      {/* Calidad + Salud */}
      <div className="grid gap-6 lg:grid-cols-3">
        <Card className="lg:col-span-2">
          <CardHeader>
            <CardTitle className="flex items-center gap-2">
              <Icons.CheckCircle2 className="w-5 h-5" /> Calidad de planes
            </CardTitle>
          </CardHeader>
          <CardContent>
            <Ring pct={calidadPlanesPct} color={hex(auth.claims?.facultad_color, '#2563eb')} />
            <p className="mt-3 text-sm text-neutral-600">
              Considera <span className="font-medium">objetivo general, perfiles, sistema de evaluación y créditos</span>.
            </p>
          </CardContent>
        </Card>

        <Card>
          <CardHeader>
            <CardTitle className="flex items-center gap-2">
              <Icons.HeartPulse className="w-5 h-5" /> Salud de asignaturas
            </CardTitle>
          </CardHeader>
          <CardContent className="space-y-2">
            <HealthRow
              to="/_authenticated/asignaturas?f=sinBibliografia"
              label="Sin bibliografía"
              value={saludAsignaturas.sinBibliografia}
            />
            <HealthRow
              to="/_authenticated/asignaturas?f=sinCriterios"
              label="Sin criterios de evaluación"
              value={saludAsignaturas.sinCriterios}
            />
            <HealthRow
              to="/_authenticated/asignaturas?f=sinContenidos"
              label="Sin contenidos"
              value={saludAsignaturas.sinContenidos}
            />
          </CardContent>
        </Card>
      </div>

      {/* Actividad reciente */}
      <Card>
        <CardHeader>
          <CardTitle className="flex items-center gap-2">
            <Icons.Activity className="w-5 h-5" /> Actividad reciente
          </CardTitle>
        </CardHeader>
        <CardContent>
          {recientes.length === 0 && (
            <div className="text-sm text-neutral-500">Sin actividad registrada.</div>
          )}
          <ul className="divide-y">
            {recientes.map(r => (
              <li key={`${r.tipo}-${r.id}`} className="py-2 flex items-center justify-between gap-3">
                <Link
                  to={r.tipo === 'plan' ? '/plan/$planId' : '/asignatura/$asignaturaId'}
                  params={r.tipo === 'plan' ? { planId: r.id } : { asignaturaId: r.id }}
                  className="truncate inline-flex items-center gap-2 hover:underline"
                  title={r.nombre}
                >
                  {r.tipo === 'plan' ? (
                    <Icons.ScrollText className="w-4 h-4 text-neutral-500" />
                  ) : (
                    <Icons.BookOpen className="w-4 h-4 text-neutral-500" />
                  )}
                  <span className="truncate">{r.nombre}</span>
                </Link>
                <span className="text-xs text-neutral-500">
                  {r.fecha ? new Date(r.fecha).toLocaleDateString() : ''}
                </span>
              </li>
            ))}
          </ul>
        </CardContent>
      </Card>
    </div>
  )
}

/* ========= Subcomponentes ========= */
function HealthRow({ label, value, to }: { label: string; value: number; to: string }) {
  const warn = value > 0
  return (
    <Link
      to={to}
      className={`flex items-center justify-between rounded-xl px-4 py-3 ring-1 ${warn
        ? 'ring-amber-300 bg-amber-50 text-amber-800 hover:bg-amber-100'
        : 'ring-neutral-200 hover:bg-neutral-50'
        } transition-colors`}
    >
      <span className="text-sm">{label}</span>
      <span className="text-lg font-semibold tabular-nums">{value}</span>
    </Link>
  )
}

/* ========= Skeleton (cuando carga) ========= */
function Pulse({ className = '' }: { className?: string }) {
  return <div className={`animate-pulse bg-neutral-200 dark:bg-neutral-800 rounded-xl ${className}`} />
}
function DashboardSkeleton() {
  return (
    <div className="p-6 space-y-8">
      <div className="rounded-3xl p-8">
        <Pulse className="h-24" />
      </div>
      <div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-4">
        {Array.from({ length: 4 }).map((_, i) => (
          <Pulse key={i} className="h-28" />
        ))}
      </div>
      <div className="grid gap-6 lg:grid-cols-3">
        <Pulse className="h-64 lg:col-span-2" />
        <Pulse className="h-64" />
      </div>
      <Pulse className="h-72" />
    </div>
  )
}
