import { useRouter } from "@tanstack/react-router"
import { useSupabaseAuth } from "@/auth/supabase"
import { useState, useEffect, useCallback } from "react"
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter } from "@/components/ui/dialog"
import { Label } from "@/components/ui/label"
import { Textarea } from "@/components/ui/textarea"
import { Input } from "@/components/ui/input"
import { CarreraCombobox, FacultadCombobox } from "@/components/users/procedencia-combobox"
import { Button } from "@/components/ui/button"
import { postAPI } from "@/lib/api"
import { supabase } from "@/auth/supabase"
import { DetailDialog } from "@/components/archivos/DetailDialog"
import type { RefRow } from "@/types/RefRow";

// ————————————————————————————————————————————————————————————————
// Utils
// ————————————————————————————————————————————————————————————————
function useDebounce<T>(value: T, delay: number): T {
  const [debouncedValue, setDebouncedValue] = useState(value);
  useEffect(() => {
    const handler = setTimeout(() => setDebouncedValue(value), delay);
    return () => clearTimeout(handler);
  }, [value, delay]);
  return debouncedValue;
}

function fileExt(title?: string) {
  const m = (title || "").match(/\.([a-z0-9]{2,5})$/i);
  return m ? m[1].toLowerCase() : "file";
}

function extIcon(ext: string) {
  // Usa íconos de lucide si ya los tienes en tu stack; si no, fallback a emojis
  const map: Record<string, string> = {
    pdf: "📄",
    doc: "📝",
    docx: "📝",
    xls: "📊",
    xlsx: "📊",
    csv: "📑",
    ppt: "🖼️",
    pptx: "🖼️",
    txt: "📃",
    md: "🗒️",
    json: "{ }",
  };
  return map[ext] || "📁";
}

// ————————————————————————————————————————————————————————————————
// Componente principal
// ————————————————————————————————————————————————————————————————
export function CreatePlanDialog({ open, onOpenChange }: { open: boolean; onOpenChange: (v: boolean) => void }) {
  const router = useRouter()
  const auth = useSupabaseAuth()
  const role = auth.claims?.role

  const [saving, setSaving] = useState(false)
  const [err, setErr] = useState<string | null>(null)

  const [facultadId, setFacultadId] = useState(auth.claims?.facultad_id ?? "")
  const [carreraId, setCarreraId] = useState(auth.claims?.carrera_id ?? "")
  const [nivel, setNivel] = useState("")
  const [prompt, setPrompt] = useState(
    "Genera un plan de estudios claro y realista: "
  )

  const [dbFiles, setDbFiles] = useState<{
    id: string;
    titulo: string;
    s3_file_path: string;
    fecha_subida?: string;
    tags?: string[];
  }[]>([])
  const [selectedFiles, setSelectedFiles] = useState<string[]>([])
  const [lastSelectedIndex, setLastSelectedIndex] = useState<number | null>(null)
  const [searchTerm, setSearchTerm] = useState("")
  const [currentPage, setCurrentPage] = useState(1)
  const itemsPerPage = 10
  const debouncedSearchTerm = useDebounce(searchTerm, 300)
  const totalPages = Math.ceil(dbFiles.length / itemsPerPage);

  const [previewRow, setPreviewRow] = useState<RefRow | null>(null);

  const lockFacultad = role === "secretario_academico" || role === "jefe_carrera"
  const lockCarrera = role === "jefe_carrera"

  

  useEffect(() => {
    async function fetchDbFiles() {
      try {
        const { data, error } = await supabase
          .from("documentos")
          .select("documentos_id, titulo_archivo, fecha_subida, tags")
          .ilike("titulo_archivo", `%${debouncedSearchTerm}%`)
          .range((currentPage - 1) * itemsPerPage, currentPage * itemsPerPage - 1);

        if (error) {
          console.error("Error fetching files from database:", error);
          return;
        }

        setDbFiles((data || []).map((file: any) => ({
          id: file.documentos_id,
          titulo: file.titulo_archivo,
          s3_file_path: `prueba-referencias/documento_${file.documentos_id}.pdf`,
          fecha_subida: file.fecha_subida,
          tags: file.tags || [],
        })));
      } catch (err) {
        console.error("Unexpected error fetching files:", err);
      }
    }

    if (open) fetchDbFiles();
  }, [open, debouncedSearchTerm, currentPage]);

  const isSelected = useCallback((path: string) => selectedFiles.includes(path), [selectedFiles]);

  const toggleSelected = useCallback((id: string) => {
    setSelectedFiles(prev => prev.includes(id) ? prev.filter(p => p !== id) : [...prev, id]);
  }, []);

  const replaceSelection = useCallback((id: string) => {
    setSelectedFiles([id]);
  }, []);

  const rangeSelect = useCallback((start: number, end: number) => {
    const [s, e] = start < end ? [start, end] : [end, start];
    const ids = dbFiles.slice(s, e + 1).map(f => f.id);
    setSelectedFiles(prev => Array.from(new Set([...prev, ...ids])));
  }, [dbFiles]);

  const handleCardClick = useCallback((e: React.MouseEvent, index: number, file: { id: string }) => {
    const id = file.id;

    if (e.shiftKey && lastSelectedIndex !== null) {
      rangeSelect(lastSelectedIndex, index);
    } else if (e.metaKey || e.ctrlKey) {
      toggleSelected(id);
      setLastSelectedIndex(index);
    } else {
      if (isSelected(id) && selectedFiles.length === 1) {
        // si ya es el único seleccionado, des-selecciona
        setSelectedFiles([]);
        setLastSelectedIndex(null);
      } else {
        replaceSelection(id);
        setLastSelectedIndex(index);
      }
    }
  }, [isSelected, lastSelectedIndex, rangeSelect, replaceSelection, selectedFiles.length, toggleSelected]);

  const clearSelection = () => {
    setSelectedFiles([]);
    setLastSelectedIndex(null);
  };

  async function crearConIA() {
    setErr(null)
    if (!carreraId) { setErr("Selecciona una carrera."); return }
    setSaving(true)
    try {
      const res = await postAPI("/api/generar/plan", {
        carreraId,
        prompt: prompt,
        insert: true,
        files: selectedFiles,
        created_by: auth.user?.id,
      })
      const newId = (res as any)?.id || (res as any)?.plan?.id || (res as any)?.data?.id
      if (newId) {
        onOpenChange(false)
        router.invalidate()
        router.navigate({ to: "/plan/$planId", params: { planId: newId } })
      } else {
        onOpenChange(false)
        router.invalidate()
      }
    } catch (e: any) {
      setErr(typeof e?.message === "string" ? e.message : "Error al generar el plan.")
    } finally {
      setSaving(false)
    }
  }

  // ————————————————————————————————————————————————————————————————
  // Render
  // ————————————————————————————————————————————————————————————————
  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="min-w-[65vw] max-w-4xl max-h-[90vh] overflow-y-auto">
        <DialogHeader>
          <DialogTitle className="font-mono">Nuevo plan de estudios (IA)</DialogTitle>
        </DialogHeader>

        <div className="grid gap-4 md:grid-cols-2">
          <div className="md:col-span-2 space-y-1">
            <Label>Prompt</Label>
            <Textarea
              value={prompt}
              onChange={(e) => setPrompt(e.target.value)}
              className="min-h-[120px]"
              placeholder="Describe cómo debe ser el plan…"
            />
          </div>

          <div className="space-y-1">
            <Label>Nivel (opcional)</Label>
            <Input value={nivel} onChange={(e) => setNivel(e.target.value)} />
          </div>

          <div className="space-y-1">
            <Label>Facultad</Label>
            <FacultadCombobox
              value={facultadId}
              onChange={(id) => { setFacultadId(id); setCarreraId("") }}
              disabled={lockFacultad}
              placeholder="Elige una facultad…"
            />
          </div>

          <div className="md:col-span-2 space-y-1">
            <Label>Carrera *</Label>
            <CarreraCombobox
              facultadId={facultadId}
              value={carreraId}
              onChange={setCarreraId}
              disabled={!facultadId || lockCarrera}
              placeholder={facultadId ? "Elige una carrera…" : "Selecciona una facultad primero"}
            />
          </div>

          <div className="md:col-span-2 space-y-1">
            <Label>Buscar archivos</Label>
            <Input
              value={searchTerm}
              onChange={(e) => setSearchTerm(e.target.value)}
              placeholder="Buscar por título..."
            />
          </div>

          {/* Toolbar de selección */}
          <div className="md:col-span-2 flex flex-wrap items-center justify-between gap-3">
            <div className="text-sm text-neutral-600">
              {selectedFiles.length > 0 ? (
                <span>
                  {selectedFiles.length} seleccionado{selectedFiles.length > 1 ? 's' : ''}
                  <button className="ml-3 underline hover:no-underline" onClick={clearSelection}>Limpiar</button>
                </span>
              ) : (
                <span>Tip: ⇧ para seleccionar rango, ⌘/Ctrl para múltiples.</span>
              )}
            </div>
          </div>

          {/* Grid de archivos con selección tipo file manager */}
          <div className="md:col-span-2 space-y-1">
            <Label>Archivos de referencia (opcional)</Label>
            <div role="grid" className="grid gap-4 xs:grid-cols-2 sm:grid-cols-2 md:grid-cols-3 xl:grid-cols-4 2xl:grid-cols-5">
              {dbFiles.map((file, index) => {
                const ext = fileExt(file.titulo);
                const selected = isSelected(file.id);
                console.log(file);
                
                return (
                  <div
                    key={file.id}
                    role="gridcell"
                    aria-selected={selected}
                    onClick={(e) => handleCardClick(e, index, file)}
                    onDoubleClick={(e) => {
                      e.stopPropagation();
                      setPreviewRow({
                        documentos_id: file.id,
                        created_by: "unknown",
                        s3_file_path: file.s3_file_path,
                        titulo_archivo: file.titulo,
                        descripcion: "Previsualización del archivo",
                        tipo_contenido: "PDF",
                        interno: true,
                        procesado: true,
                        fuente_autoridad: "",
                        fecha_subida: file.fecha_subida ?? null,
                        tags: file.tags ?? null,
                        instrucciones: "",
                      })
                    }}
                    onKeyDown={(e) => {
                      if (e.key === 'Enter' || e.key === ' ') {
                        e.preventDefault();
                        handleCardClick(e as any, index, file);
                      }
                    }}
                    className={[
                      "group relative rounded-2xl border bg-white p-4 text-left shadow-sm transition",
                      "hover:shadow-md focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-500",
                      selected ? "border-blue-500 ring-2 ring-blue-500 shadow-md" : "border-neutral-200 hover:border-neutral-300",
                    ].join(' ')}
                  >
                    {/* Outline animado tipo file manager */}
                    <span className={[
                      "pointer-events-none absolute inset-0 rounded-2xl ring-2 ring-blue-500",
                      "opacity-0 group-aria-selected:opacity-100 group-focus:opacity-100 transition-opacity",
                    ].join(' ')} />

                    <div className="flex items-start gap-3">
                      <div className="flex h-10 w-10 shrink-0 items-center justify-center rounded-xl border bg-neutral-50">
                        <span className="text-lg" aria-hidden>{extIcon(ext)}</span>
                      </div>
                      <div className="min-w-0 flex-1">
                        <h3 className="font-semibold text-sm md:text-base truncate" title={file.titulo}>{file.titulo}</h3>
                        {file.fecha_subida ? (
                          <p className="text-xs text-neutral-600">{new Date(file.fecha_subida).toLocaleDateString()}</p>
                        ) : (
                          <p className="text-xs text-neutral-500">Fecha desconocida</p>
                        )}
                        
                        {file.tags && file.tags.length > 0 && (
                          <div className="mt-2 flex flex-wrap gap-1.5">
                            {file.tags.map((tag, i) => (
                              <span key={i} className="text-[10px] px-2 py-0.5 bg-neutral-100 text-neutral-700 rounded-full">#{tag}</span>
                            ))}
                          </div>
                        )}
                      </div>
                    </div>

                    {/* Acciones on-hover */}
                    <div className="absolute right-3 top-3 flex gap-2 opacity-0 group-hover:opacity-100 transition-opacity">
                      <Button
                        variant="outline"
                        size="sm"
                        onClick={(e) => {
                          e.stopPropagation();
                          setPreviewRow({
                            documentos_id: file.id,
                            created_by: "unknown",
                            s3_file_path: file.s3_file_path,
                            titulo_archivo: file.titulo,
                            descripcion: "Previsualización del archivo",
                            tipo_contenido: "PDF",
                            interno: true,
                            procesado: true,
                            fuente_autoridad: "",
                            fecha_subida: file.fecha_subida ?? null,
                            tags: file.tags ?? null,
                            instrucciones: "",
                          })
                        }}
                      >Previsualizar</Button>
                    </div>

                    {/* Footer compacto */}
                    <div className="mt-4 flex items-center justify-between text-xs text-neutral-600">
                      <span className="truncate">{ext.toUpperCase()}</span>
                      {selected ? <span className="font-medium">Seleccionado</span> : <span className="opacity-60">Click para seleccionar</span>}
                    </div>
                  </div>
                )
              })}

              {dbFiles.length === 0 && (
                <p className="text-sm text-neutral-500">No se encontraron archivos.</p>
              )}
            </div>

            {/* Paginación mejorada */}
            {dbFiles.length > itemsPerPage && (
              <div className="mt-4 flex flex-wrap items-center justify-between gap-3">
                <div className="text-sm text-neutral-700">Página {currentPage} de {totalPages}</div>
                <div className="flex items-center gap-2">
                  <Button
                    variant="outline"
                    size="sm"
                    disabled={currentPage === 1}
                    onClick={() => setCurrentPage((p) => Math.max(p - 1, 1))}
                  >Anterior</Button>
                  <Input
                    className="h-8 w-16 text-center"
                    value={currentPage}
                    onChange={(e) => {
                      const v = parseInt(e.target.value || '1', 10);
                      if (!isNaN(v)) setCurrentPage(Math.min(Math.max(v, 1), totalPages));
                    }}
                  />
                  <Button
                    variant="outline"
                    size="sm"
                    disabled={currentPage === totalPages}
                    onClick={() => setCurrentPage((p) => Math.min(p + 1, totalPages))}
                  >Siguiente</Button>
                </div>
              </div>
            )}
          </div>
        </div>

        {err && <div className="text-sm text-red-600">{err}</div>}

        <DialogFooter className="flex flex-col-reverse sm:flex-row gap-2">
          <Button variant="outline" className="w-full sm:w-auto" onClick={() => onOpenChange(false)}>Cancelar</Button>
          <Button className="w-full sm:w-auto" onClick={crearConIA} disabled={saving}>
            {saving ? "Generando…" : "Generar y crear"}
          </Button>
        </DialogFooter>
      </DialogContent>

      {previewRow && (
        <DetailDialog
          row={previewRow}
          onClose={() => setPreviewRow(null)}
        />
      )}
    </Dialog>
  )
}
