import React, { useEffect, useState } from "react" import { supabase } from "@/auth/supabase" import type { PlanTextFields } from "../planes/academic-sections"; // 🔹 SIMULACIÓN DE ICONO LUCIDE-REACT const Paperclip = (props) => ( ); // 🔹 SIMULACIÓN DE SHADCN/UI const Dialog = ({ open, onOpenChange, children }) => open ?
{children}
: null; const DialogContent = ({ className, children }) =>
e.stopPropagation()}>{children}
; const DialogHeader = ({ children }) =>
{children}
; const DialogTitle = ({ className, children }) =>

{children}

; const Button = ({ onClick, disabled, className, variant, children }) => ( ); const Card = ({ className, children }) =>
{children}
; const CardContent = ({ className, children }) =>
{children}
; const ScrollArea = ({ className, children }) =>
{children}
; // ==================================================================== type AIChatModalProps = { open: boolean onClose: () => void edgeFunctionUrl: string context?: { section?: string fieldKey?: keyof PlanTextFields originalText?: string } onAccept?: (newText: string) => void } export default function AIChatModal({ open, onClose, edgeFunctionUrl, context, onAccept }: AIChatModalProps) { const [files, setFiles] = useState([]) const [attachedFile, setAttachedFile] = useState(null) const [attachedPreview, setAttachedPreview] = useState(null) const [messages, setMessages] = useState<{ role: string; content: string }[]>([]) const [input, setInput] = useState("") const [loading, setLoading] = useState(false) // Referencia para desplazar al final del chat const messagesEndRef = React.useRef(null); const scrollToBottom = () => messagesEndRef.current?.scrollIntoView({ behavior: "smooth" }) useEffect(scrollToBottom, [messages]) useEffect(() => { if (!open) { // 🧹 Limpia mensajes y archivos al cerrar setMessages([]) setInput("") setAttachedFile(null) setAttachedPreview(null) } else if (context) { // 🧩 Muestra el contexto inicial al abrir setMessages([ { role: "system", content: `Contexto: ${context.section}\nTexto original:\n${context.originalText || "—"}`, }, ]) } }, [open, context]) // 🔹 Obtener lista de archivos del Vector Store (Lógica de API original) useEffect(() => { if (!open) return const fetchVectorFiles = async () => { // Nota: La verificación de Supabase ahora pasa por el mock. if (typeof supabase === 'undefined' || !supabase.auth) { console.error("Supabase no está disponible (Simulación). Saltando fetch de archivos."); return; } try { setLoading(true) const { data: { session } } = await supabase.auth.getSession() const token = session?.access_token // 🟢 TU LÓGICA DE FETCH ORIGINAL const res = await fetch(`${edgeFunctionUrl}?action=list_files`, { headers: { Authorization: `Bearer ${token}` }, }) const data = await res.json() if (data.files) setFiles(data.files) else console.warn("No se encontraron archivos en el vector store.") } catch (err) { console.error("Error al cargar archivos del vector store:", err) } finally { setLoading(false) } } fetchVectorFiles() }, [open, edgeFunctionUrl]) // 📎 Adjuntar archivo const handleAttach = (e: React.ChangeEvent) => { const file = e.target.files?.[0] if (!file) return setAttachedFile(file) setAttachedPreview(file.name) } // 🚀 Enviar prompt o archivo al Edge Function (Lógica de API original) const handleSend = async () => { if (!input.trim() && !attachedFile) return // 🧩 Crear el mensaje visible del usuario let userMessageContent = input.trim() if (attachedFile) { userMessageContent += (userMessageContent ? " | " : "") + `Adjunto: ${attachedFile.name}` } if (!userMessageContent && attachedFile) { userMessageContent = `Consulta de archivo: ${attachedFile.name}` } setMessages((prev) => [...prev, { role: "user", content: userMessageContent }]) setInput("") setLoading(true) try { if (typeof supabase === "undefined" || !supabase.functions) { throw new Error("Supabase no está disponible o no soporta Edge Functions.") } const formData = new FormData() // 🧠 Construimos un prompt limpio con el contexto del campo const contextText = context?.originalText || "Sin texto original" const section = context?.section ? `Sección: ${context.section}` : "" const field = context?.fieldKey ? `Campo: ${context.fieldKey}` : "" const fullPrompt = ` ${section} ${field} Texto original: ${contextText} Solicitud del usuario: ${input} Responde con una versión mejorada del texto, sin agregar frases como “Aquí tienes” ni explicaciones. `.trim() formData.append("prompt", fullPrompt) if (attachedFile) formData.append("file", attachedFile) // 🟢 Llamada a la Edge Function const { data, error } = await supabase.functions.invoke("simple-chat", { body: formData, }) if (error) throw error setMessages((prev) => [ ...prev, { role: "assistant", content: data?.text || "Sin respuesta del modelo." }, ]) } catch (err: any) { console.error("Error al enviar prompt:", err) setMessages((prev) => [ ...prev, { role: "assistant", content: "Ocurrió un error al conectar con la API." }, ]) } finally { setLoading(false) setAttachedFile(null) setAttachedPreview(null) } } return (           {/* DialogContent ya define el tamaño h-[85vh] y es flex-col */}               {/* Encabezado fijo (flex-shrink-0) */}                   Asistente Inteligente         {/* CONTENEDOR PRINCIPAL QUE AHORA GESTIONA EL SCROLL DEL CONTENIDO */} {/* flex-1: toma el espacio restante. overflow-y-auto: permite scroll si el contenido se desborda */}        
{/* Contenido que originalmente estaba justo debajo del header */}
          {/* 📂 Archivos del Vector Store */}                       {/* Se mantiene flex-1 en CardContent para el ScrollArea */}                          

Archivos del Vector Store

              {/* ScrollArea toma el espacio disponible (flex-1) */}                               {files.length === 0 ? (                  

                    {loading ? "Cargando archivos..." : "No hay archivos cargados."}                  

                ) : (                  
                        {files.map((file) => (                      
  •                         {file.name}                        

    {file.path}

                         
  •                     ))}                  
                )}              
             
                             
           
         
          {/* 💬 Chat con GPT */}                                    

Chat con IA

              {/* Mensajes - EL CONTENEDOR QUE DEBE HACER SCROLL */}                
                {messages.length === 0 ? (                  

                    Inicia una conversación...                  

                ) : (                   messages.map((m, i) => (                    
                      {m.role === "user" ? "Tú:" : "IA:"}{" "}                       {m.content}                    
                  ))                 )}                 {loading && (                  
                                                                                                        La IA está respondiendo...                  
                )}                
             
              {/* Archivo adjunto - flex-shrink-0 */}               {attachedPreview && (                
                                                          {attachedPreview}                                                    
              )}               {/* Entrada de texto y enviar - flex-shrink-0 */}