import { createFileRoute, useRouter, Link, useNavigate } from "@tanstack/react-router"
import { useMemo, useState } from "react"
import { supabase, useSupabaseAuth } from "@/auth/supabase"
import { Input } from "@/components/ui/input"
import { Button } from "@/components/ui/button"
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
import { Badge } from "@/components/ui/badge"
import * as Icons from "lucide-react"
import { Plus, RefreshCcw, Building2 } from "lucide-react"
import { InfoChip } from "@/components/planes/InfoChip"
import { CreatePlanDialog } from "@/components/planes/CreatePlanDialog"
import { chipTint } from "@/components/planes/chipTint"
import { z } from "zod"
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select"

export type PlanDeEstudios = {
  id: string
  nombre: string
  nivel: string | null
  duracion: string | null
  total_creditos: number | null
  estado: string | null
  fecha_creacion: string | null
  carrera_id: string | null
}
type PlanRow = PlanDeEstudios & {
  carreras: {
    id: string
    nombre: string
    facultades?: {
      id: string
      nombre: string
      color?: string | null
      icon?: string | null
    } | null
  } | null
}

const planSearchSchema = z.object({
  plan: z.string().nullable(),
  facultad: z.string().nullable().optional(),
  carrera: z.string().nullable().optional(),
})

export const Route = createFileRoute("/_authenticated/planes")({
  component: RouteComponent,
  loader: async () => {
    const { data, error } = await supabase
      .from("plan_estudios")
      .select(`
        *,
        carreras (
          id,
          nombre,
          facultades:facultades ( id, nombre, color, icon )
        )
      `)
      .order("fecha_creacion", { ascending: false })
      .limit(100)
    if (error) throw new Error(error.message)
    return (data ?? []) as PlanRow[]
  },
  validateSearch: planSearchSchema,
})

function RouteComponent() {
  const auth = useSupabaseAuth()
  const { plan, facultad, carrera } = Route.useSearch()
  const [openCreate, setOpenCreate] = useState(false)
  const data = Route.useLoaderData() as PlanRow[]
  const router = useRouter()
  const navigate = useNavigate({ from: Route.fullPath })

  const showFacultad =
    auth.claims?.role === "lci" || auth.claims?.role === "vicerrectoria"
  const showCarrera =
    showFacultad || auth.claims?.role === "secretario_academico"

  // 🟣 Lista única de facultades
  const facultadesList = useMemo(() => {
    const unique = new Map<string, string>()
    data?.forEach((p) => {
      const fac = p.carreras?.facultades
      if (fac?.id && fac?.nombre) unique.set(fac.id, fac.nombre)
    })
    return Array.from(unique.entries())
  }, [data])

  // 🎓 Lista de carreras según facultad seleccionada
  const carrerasList = useMemo(() => {
    const unique = new Map<string, string>()
    data?.forEach((p) => {
      if (
        p.carreras?.id &&
        p.carreras?.nombre &&
        (!facultad || p.carreras?.facultades?.id === facultad)
      ) {
        unique.set(p.carreras.id, p.carreras.nombre)
      }
    })
    return Array.from(unique.entries())
  }, [data, facultad])

  // 🧩 Filtrado general
  const filtered = useMemo(() => {
    const term = plan?.trim().toLowerCase()
    let results = data ?? []

    if (term) {
      results = results.filter((p) =>
        [p.nombre, p.nivel, p.estado, p.carreras?.nombre, p.carreras?.facultades?.nombre]
          .filter(Boolean)
          .some((v) => String(v).toLowerCase().includes(term))
      )
    }

    if (facultad && facultad !== "todas") {
      results = results.filter((p) => p.carreras?.facultades?.id === facultad)
    }

    if (carrera && carrera !== "todas") {
      results = results.filter((p) => p.carreras?.id === carrera)
    }

    return results
  }, [plan, facultad, carrera, data])

  return (
    <div className="space-y-4">
      <Card>
        <CardHeader className="flex flex-col gap-2 md:flex-row md:items-center md:justify-between">
          <CardTitle className="text-xl font-mono">Planes de estudio</CardTitle>

          <div className="flex w-full flex-col md:flex-row items-center gap-2 md:w-auto">
            {/* 🔍 Buscador */}
            <div className="relative w-full md:w-80">
              <Input
                value={plan ?? ""}
                onChange={(e) =>
                  navigate({ search: { plan: e.target.value, facultad, carrera } })
                }
                placeholder="Buscar por nombre, nivel, estado…"
              />
            </div>

            {/* 🏛️ Filtro por facultad */}
            <Select
              value={facultad ?? "todas"}
              onValueChange={(val) =>
                navigate({ search: { plan, facultad: val, carrera: "todas" } })
              }
            >
              <SelectTrigger className="w-[200px]">
                <SelectValue placeholder="Filtrar por facultad" />
              </SelectTrigger>
              <SelectContent>
                <SelectItem value="todas">Todas las facultades</SelectItem>
                {facultadesList.map(([id, nombre]) => (
                  <SelectItem key={id} value={id}>
                    {nombre}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>

            {/* 🎓 Filtro por carrera (según facultad) */}
            {facultad && facultad !== "todas" && (
              <Select
                value={carrera ?? "todas"}
                onValueChange={(val) =>
                  navigate({ search: { plan, facultad, carrera: val } })
                }
              >
                <SelectTrigger className="w-[200px]">
                  <SelectValue placeholder="Filtrar por carrera" />
                </SelectTrigger>
                <SelectContent>
                  <SelectItem value="todas">Todas las carreras</SelectItem>
                  {carrerasList.map(([id, nombre]) => (
                    <SelectItem key={id} value={id}>
                      {nombre}
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
            )}


            {/* 🔁 Recargar */}
            <Button
              variant="outline"
              size="icon"
              onClick={() => router.invalidate()}
              title="Recargar"
            >
              <RefreshCcw className="h-4 w-4" />
            </Button>

            {/* ➕ Nuevo plan */}
            <Button onClick={() => setOpenCreate(true)}>
              <Plus className="mr-2 h-4 w-4" /> Nuevo plan
            </Button>
          </div>
        </CardHeader>

        {/* GRID de tarjetas */}
        <CardContent>
          <div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4">
            {filtered?.map((p) => {
              const fac = p.carreras?.facultades
              const styles = chipTint(fac?.color)
              const IconComp =
                (fac?.icon && (Icons as any)[fac.icon]) || Building2

              return (
                <Link
                  key={p.id}
                  to="/plan/$planId"
                  mask={{ to: "/plan/$planId", params: { planId: p.id } }}
                  className="group relative overflow-hidden rounded-3xl bg-white shadow-sm ring-1 transition-all hover:shadow-md hover:-translate-y-0.5"
                  params={{ planId: p.id }}
                  style={styles}
                >
                  <div className="relative p-5 h-40 flex flex-col justify-between">
                    <div className="flex items-center gap-3">
                      <span
                        className="inline-flex items-center justify-center rounded-2xl border px-2.5 py-2"
                        style={{
                          borderColor: styles.borderColor as string,
                          background: "rgba(255,255,255,.6)",
                        }}
                      >
                        <IconComp className="w-6 h-6" />
                      </span>
                      <div className="min-w-0">
                        <div className="font-semibold truncate">{p.nombre}</div>
                        <div className="text-xs text-neutral-600 truncate">
                          {p.nivel ?? "—"}{" "}
                          {p.duracion ? `· ${p.duracion}` : ""}
                        </div>
                      </div>
                    </div>

                    <div className="mt-3 flex items-center gap-2">
                      <div className="min-w-0 flex-1 flex flex-wrap items-center gap-2">
                        {showCarrera && p.carreras?.nombre && (
                          <InfoChip
                            icon={<Icons.GraduationCap className="h-3 w-3" />}
                            label={p.carreras.nombre}
                          />
                        )}
                        {showFacultad && fac?.nombre && (
                          <InfoChip
                            icon={<Icons.Building2 className="h-3 w-3" />}
                            label={fac.nombre}
                            tint={fac.color}
                          />
                        )}
                      </div>

                      {p.estado && (
                        <Badge
                          variant="outline"
                          className="bg-white/60"
                          style={{
                            borderColor:
                              chipTint(fac?.color).borderColor as string,
                          }}
                        >
                          {p.estado.length > 10
                            ? `${p.estado.slice(0, 10)}…`
                            : p.estado}
                        </Badge>
                      )}
                    </div>
                  </div>
                </Link>
              )
            })}
          </div>

          {!filtered?.length && (
            <div className="text-center text-sm text-muted-foreground py-10">
              Sin resultados
            </div>
          )}
        </CardContent>
      </Card>

      <CreatePlanDialog open={openCreate} onOpenChange={setOpenCreate} />
    </div>
  )
}
