import React, { useEffect, useRef, useState } from "react";
import { supabase } from "@/auth/supabase";
import ReactMarkdown from "react-markdown"

/* ---------- UI Mocks (sin cambios) ---------- */
const Paperclip = (props) => (
  <svg {...props} xmlns="http://www.w3.org/2000/svg" width="24" height="24"
    viewBox="0 0 24 24" fill="none" stroke="currentColor"
    strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
    <path d="m21.44 11.05-9.19 9.19a6 6 0 0 1-8.49-8.49l9.19-9.19a4 4 0 0 1 5.66 5.66l-9.2 9.19a2 2 0 0 1-2.83-2.83l8.49-8.48"/>
  </svg>
);

const Dialog = ({ open, onOpenChange, children }) =>
  open ? <div className="fixed inset-0 bg-black/50 flex items-center justify-center z-50 p-4" onClick={onOpenChange}>{children}</div> : null;
const DialogContent = ({ className, children }) =>
  <div className={`bg-white rounded-xl shadow-2xl transform transition-all max-w-6xl w-[95vw] h-[85vh] p-6 flex flex-col ${className}`}
    onClick={(e) => e.stopPropagation()}>{children}</div>;
const DialogHeader = ({ children }) => <div className="pb-4 border-b border-gray-200">{children}</div>;
const DialogTitle = ({ className, children }) => <h2 className={`text-xl font-bold ${className}`}>{children}</h2>;
const Button = ({ onClick, disabled, className, variant, children }) => (
  <button onClick={onClick} disabled={disabled}
    className={`px-4 py-2 rounded-lg text-sm font-medium transition-colors 
      ${variant === "outline"
        ? "bg-white border border-gray-300 text-gray-700 hover:bg-gray-50"
        : "bg-blue-600 text-white hover:bg-blue-700"}
      ${disabled ? "opacity-50 cursor-not-allowed" : ""} ${className}`}>
    {children}
  </button>
);
const Card = ({ className, children }) => <div className={`bg-white rounded-2xl shadow-md ${className}`}>{children}</div>;
const CardContent = ({ className, children }) => <div className={`p-4 ${className}`}>{children}</div>;
const ScrollArea = ({ className, children }) => <div className={`overflow-y-auto ${className}`}>{children}</div>;

/* ------------- COMPONENT ------------- */
export default function AIChatModal({ open, onClose, context, onAccept, plan_format }) {
  const [vectorStores, setVectorStores] = useState([]);
  const [vectorFiles, setVectorFiles] = useState([]);
  const [selectedVectorFile, setSelectedVectorFile] = useState(null);

  const [attachedFiles, setAttachedFiles] = useState([]);
  const [attachedPreviews, setAttachedPreviews] = useState([]);

  const [messages, setMessages] = useState([]);
  const [input, setInput] = useState("");

  const [loading, setLoading] = useState(false);
  const [loadingFiles, setLoadingFiles] = useState(false);
  const [loadingVectors, setLoadingVectors] = useState(false);

  const [conversationId, setConversationId] = useState(null);
  const [creatingConversation, setCreatingConversation] = useState(false); // control para esperar

  const messagesEndRef = useRef(null);
  const scrollToBottom = () => messagesEndRef.current?.scrollIntoView({ behavior: "smooth" });
  useEffect(scrollToBottom, [messages]);

  const normalizeInvokeResponse = (resp) => {
  if (!resp) return null;

  // cuando invocas funciones, Supabase siempre regresa:
  // { data: "...string...", error: null, response: {} }
  const raw = resp.data;

  if (typeof raw === "string") {
    try {
      return JSON.parse(raw);
    } catch (e) {
      console.warn("❗ No se pudo parsear resp.data:", raw);
      return null;
    }
  }

  // si ya viene como objeto
  if (typeof raw === "object" && raw !== null) return raw;

  return null;
};


  // Al abrir: reset o crear conversación
  useEffect(() => {
    console.log(context.cont_conversation);
    console.log(context);
    
    if (!open) {
      // si ya existe una conversación la eliminamos
      if (conversationId) {
        deleteConversation(conversationId).catch((e) => console.error(e));
      }
      setMessages([]);
      setInput("");
      setSelectedVectorFile(null);
      setAttachedFiles([]);
      setAttachedPreviews([]);
      setConversationId(null);
      return;
    }

    // inyectar contexto como system message
    if (context) {
      setMessages([
        {
          role: "system",
          content: `Contexto académico:\n${context.section || "—"}\n\nTexto original:\n${context.originalText || "—"}`
        }
      ]);
    } else {
      setMessages(prev => prev); // no hacer nada si no hay contexto
    }

    // crear conversación y esperar a que termine antes de permitir enviar
    (async () => {
      await createConversation();
      // tras crear podemos también cargar vector stores
      fetchVectorStores();
    })();

  }, [open]);

  // --------- CREATE CONVERSATION (robusto) ----------
  const createConversation = async () => {
  try {
    setCreatingConversation(true);

    const { data: { session } } = await supabase.auth.getSession();
    const token = session?.access_token;

    // llamada
    const resp = await supabase.functions.invoke("conversation-format", {
      headers: { Authorization: `Bearer ${token}` },
      body: { action: "start" , role:"system", content:context.cont_conversation,   }
    });

    console.log("createConversation -> raw resp:", resp);

    // resp puede ser { data: "...json string..." } o { data: { ... } }
    let parsed = null;

    if (typeof resp?.data === "string") {
      try {
        parsed = JSON.parse(resp.data);
      } catch (e) {
        console.warn("No se pudo parsear resp.data como JSON:", e, resp.data);
        parsed = null;
      }
    } else if (typeof resp?.data === "object" && resp.data !== null) {
      parsed = resp.data;
    } else {
      // fallback: quizá la respuesta viene en resp (sin data)
      parsed = resp;
    }

    console.log("createConversation -> parsed payload:", parsed);

    // buscar el id en varios lugares (robusto)
    const convId =
      parsed?.conversationId ||
      parsed?.data?.conversationId ||
      parsed?.data?.id ||
      parsed?.id ||
      parsed?.conversation_id ||
      parsed?.data?.conversation_id;

    if (!convId) {
      console.warn("No se encontró conversationId en la respuesta parseada:", parsed);
      setCreatingConversation(false);
      return;
    }

    setConversationId(convId);
    console.log("🟢 Conversación creada y guardada:", convId);

  } catch (err) {
    console.error("Error creando conversación:", err);
  } finally {
    setCreatingConversation(false);
  }
};


  // --------- DELETE CONVERSATION (robusto) ----------
  const deleteConversation = async (convIdParam) => {
    try {
      const convIdToUse = convIdParam ?? conversationId;
      if (!convIdToUse) return;
      const { data: { session } } = await supabase.auth.getSession();
      const token = session?.access_token;

      // algunas implementations esperan { action: "end", conversationId }, otras { action: "end", id }
      const { data, error } = await supabase.functions.invoke("conversation-format", {
        headers: { Authorization: `Bearer ${token}` },
        body: { action: "end", conversationId: convIdToUse }
      });

      console.log("deleteConversation -> response:", data);
      setConversationId(null);
    } catch (err) {
      console.error("Error eliminando conversación:", err);
    }
  };

  // ---------- CONVERT FILE TO BASE64 ----------
  const fileToBase64 = (file) =>
    new Promise((resolve, reject) => {
      const reader = new FileReader();
      reader.onerror = (e) => reject(e);
      reader.onload = () => resolve(reader.result.split(",")[1]);
      reader.readAsDataURL(file);
    });

  // ---------- SEND MESSAGE (usa conversationId) ----------
  const handleConversation = async ({ text }) => {
    console.log(plan_format);
    
    if (!conversationId) {
      console.warn("No hay conversación activa todavía. conversationId:", conversationId);
      // si no hay conv, opcionalmente intentar crear una sin que el usuario note
      return;
    }

    try {
      setLoading(true);
      const { data: { session } } = await supabase.auth.getSession();
      const token = session?.access_token;

      let filesInput = [];
 
      if (attachedFiles.length > 0) {
  for (const file of attachedFiles) {
    const base64 = await fileToBase64(file);
    filesInput.push({
      type: "input_file",
      filename: file.name,
      file_data: `data:${file.type};base64,${base64}`
    });
  }
}

      if (selectedVectorFile) {
        // si el archivo del vector viene sólo con id
        filesInput.push({
          type: "input_file",
          file_id: selectedVectorFile.id
        });
      }

      const payload = {
        action: "message",
        format: plan_format,
        conversationId,
        vectorStoreId: selectedVectorFile?.vector_store_id ?? null,
        fileIds: selectedVectorFile ? [selectedVectorFile.id] : [],
        input: [
          {
            role: "user",
            content: [
              { type: "input_text", text },
              ...filesInput
            ]
          }
        ]
      };
      const { data: invokeData, error } = await supabase.functions.invoke(
        "conversation-format",
        {
          headers: { Authorization: `Bearer ${token}` },
          body: payload
        }
      );

      if (error) throw error;

      console.log("handleConversation -> RAW invokeData:", invokeData);

      const parsed = normalizeInvokeResponse({ data: invokeData });
      console.log("handleConversation -> PARSED:", parsed);

      // 🔥 EXTRACTOR DEFINITIVO
      let assistantText = null;

      // 1) directo
      if (parsed?.data?.output_text) {
        assistantText = parsed.data.output_text;
      }

      // 2) buscar el message
      if (!assistantText && Array.isArray(parsed?.data?.output)) {
        const msgBlock = parsed.data.output.find(o => o.type === "message");
        if (msgBlock?.content?.[0]?.text) {
          assistantText = msgBlock.content[0].text;
        }
      }

      // 3) fallback
      assistantText = assistantText || "Sin respuesta del modelo.";

      setMessages(prev => [
        ...prev,
        { role: "assistant", content: cleanAssistantResponse(assistantText) }
      ]);


      setAttachedFiles([]);
      setAttachedPreviews([]);


    } catch (err) {
      console.error("Error en handleConversation:", err);
      setMessages(prev => [...prev, { role: "assistant", content: "Ocurrió un error al procesar tu mensaje." }]);
    } finally {
      setLoading(false);
    }
  };

  // ---------- VECTORES ----------
  const fetchVectorStores = async () => {
    try {
      setLoadingVectors(true);
      const { data: { session } } = await supabase.auth.getSession();
      const token = session?.access_token;

      const { data, error } = await supabase.functions.invoke("files-and-vector-stores-api", {
        headers: { Authorization: `Bearer ${token}` },
        body: { module: "vectorStores", action: "list" }
      });

      if (error) throw error;
      setVectorStores(Array.isArray(data) ? data : (data?.data ?? []));
    } catch (err) {
      console.error("Error loading vector stores:", err);
      setVectorStores([]);
    } finally {
      setLoadingVectors(false);
    }
  };

  useEffect(() => {
    if (open) fetchVectorStores();
  }, [open]);

  const loadFilesForVector = async (vectorStoreId) => {
    try {
      setLoadingFiles(true);
      const { data: { session } } = await supabase.auth.getSession();
      const token = session?.access_token;

      const { data, error } = await supabase.functions.invoke("files-and-vector-stores-api", {
        headers: { Authorization: `Bearer ${token}` },
        body: { module: "vectorStoreFiles", action: "list", params: { vector_store_id: vectorStoreId } }
      });

      if (error) throw error;
      setVectorFiles(Array.isArray(data) ? data : (data?.data ?? []));
    } catch (err) {
      console.error("Error loading vector files:", err);
      setVectorFiles([]);
    } finally {
      setLoadingFiles(false);
    }
  };

  // ---------- UI helpers ----------
 const handleAttach = (e) => {
  const files = Array.from(e.target.files);
  if (!files.length) return;

  setAttachedFiles(prev => [...prev, ...files]);
  setAttachedPreviews(prev => [...prev, ...files.map(f => f.name)]);
};


  const handleSelectVectorFile = (file) => {
    setSelectedVectorFile(file);
  };

  // ---------- Send flow ----------
  const handleSend = async () => {
    if (!input.trim() && attachedFiles.length === 0 && !selectedVectorFile) return;

    // esperar si aún se está creando la conversación
    if (creatingConversation) {
      console.log("Esperando a que se cree la conversación...");
      // opcional: podrías mostrar un toast; aquí simplemente retornamos
      return;
    }

    if (!conversationId) {
      console.warn("No hay conversationId — intentaremos crear una ahora.");
      await createConversation();
      if (!conversationId) {
        setMessages(prev => [...prev, { role: "assistant", content: "No se pudo crear la conversación. Intenta de nuevo." }]);
        return;
      }
    }

    const userText = input.trim() || (selectedVectorFile ? `Consultar archivo vector: ${selectedVectorFile.filename || selectedVectorFile.id}` : "");
    setMessages(prev => [...prev, { role: "user", content: userText }]);
    setInput("");

    await handleConversation({ text: userText });
  };

  const handleApply = () => {
    const last = [...messages].reverse().find(m => m.role === "assistant");
    if (last && onAccept) {
      onAccept(last.content);
      onClose();
    }
  };
    const cleanAssistantResponse = (text) => {
    if (!text) return text;

    // Frases que quieres eliminar (puedes agregar más)
    const patterns = [
      /^claro[, ]*/i,
      /^por supuesto[, ]*/i,
      /^aquí tienes[, ]*/i,
      /^con gusto[, ]*/i,
      /^hola[, ]*/i,
      /^perfecto[, ]*/i,
      /^entendido[, ]*/i,
      /^muy bien[, ]*/i,
      /^ok[, ]*/i,
    ];

    let cleaned = text.trim();

    for (const p of patterns) {
      cleaned = cleaned.replace(p, "").trim();
    }

    return cleaned;
  };


  return (
    <Dialog open={open} onOpenChange={onClose}>
      <DialogContent className="max-w-6xl w-[95vw] h-[85vh] p-6 flex flex-col relative">
         {/* Botón siempre visible */}
          <button
            onClick={onClose}
            className="absolute top-3 right-3 text-gray-400 hover:text-gray-600 transition z-50"
          >
            ✕
          </button>
        <DialogHeader>
          <DialogTitle>Asistente Inteligente</DialogTitle>
        </DialogHeader>

        <div className="flex-1 pt-4 min-h-0">
          <div className="flex gap-6 h-full min-h-0">

            {/* Left: vectors */}
            <Card className="w-1/3 min-w-[250px] max-w-sm flex flex-col bg-muted/20 border border-gray-200 rounded-2xl">
              <CardContent className="flex flex-col flex-1 p-4">
                <h3 className="font-semibold text-sm mb-3">Vector Stores</h3>
                <ScrollArea className="flex-1">
                  {loadingVectors ? (
                    <p className="text-gray-500 text-sm text-center mt-10">Cargando vector stores...</p>
                  ) : vectorStores.length === 0 ? (
                    <p className="text-gray-500 text-sm text-center mt-10">No hay vector stores.</p>
                  ) : (
                    <ul className="space-y-2">
                      {vectorStores.map((vector) => (
                        <li key={vector.id}
                          onClick={() => loadFilesForVector(vector.id)}
                          className="border cursor-pointer hover:bg-blue-50 p-2 rounded-lg bg-white"
                        >
                          <strong className="truncate">{vector.name || vector.id}</strong>
                          <p className="text-xs text-gray-400 truncate">{vector.description || vector.id}</p>
                        </li>
                      ))}
                    </ul>
                  )}
                </ScrollArea>

                <div className="mt-4">
                  <h4 className="font-semibold text-sm mb-2">Archivos del Vector</h4>
                  {loadingFiles ? (
                    <p className="text-sm text-gray-500">Cargando archivos...</p>
                  ) : selectedVectorFile ? (
                    <div className="text-sm text-gray-700 mb-2">
                      Seleccionado: <strong>{selectedVectorFile.filename ?? selectedVectorFile.id}</strong>
                    </div>
                  ) : (
                    <p className="text-sm text-gray-500">Selecciona un archivo del vector</p>
                  )}

                  <ul className="space-y-2 max-h-40 overflow-auto mt-2">
                    {vectorFiles.map((file) => (
                      <li key={file.id}
                        onClick={() => handleSelectVectorFile(file)}
                        className={`p-2 rounded-lg cursor-pointer border ${selectedVectorFile?.id === file.id ? "bg-blue-50 border-blue-300" : "bg-white"}`}
                      >
                        <div className="text-sm font-medium">{file.filename}</div>
                        <div className="text-xs text-gray-400">{file.id}</div>
                      </li>
                    ))}
                  </ul>
                </div>

                <div className="mt-4 flex-shrink-0">
                  <Button variant="outline" className="w-full" onClick={() => alert("Funcionalidad Subir a vector store no implementada aquí")}>Subir archivo (vector)</Button>
                </div>
              </CardContent>
            </Card>

            {/* Right: Chat */}
            <Card className="flex-1 flex flex-col min-w-[350px] bg-background border border-gray-200 rounded-2xl">
              <CardContent className="flex flex-col flex-1 p-4 min-h-0">

                <h3 className="font-semibold text-sm mb-3 flex-shrink-0">Chat con IA</h3>

                <div className="flex-1 flex flex-col min-h-0">
                  {/* CONTENEDOR SCROLL DE LOS MENSAJES */}
                  <div className="flex-1 overflow-y-auto min-h-0 border border-gray-200 rounded-lg p-3 space-y-3 bg-gray-50 break-words whitespace-pre-wrap">
                    {messages.length === 0 ? (
                    <p className="text-gray-400 text-sm text-center mt-10">Inicia una conversación...</p>
                  ) : (
                    messages.map((m, i) => (
                      <div key={i} className={`break-words whitespace-pre-wrap p-3 rounded-xl shadow-sm max-w-[85%] ${m.role === "user" ? "bg-blue-50 text-blue-800 ml-auto" : m.role === "assistant" ? "bg-white text-gray-800 mr-auto border border-gray-200" : "bg-gray-100 text-gray-700 mr-auto"}`}>
                        <strong className="font-bold">{m.role === "user" ? "Tú:" : m.role === "assistant" ? "IA:" : "Sistema:"}</strong>{" "}
                        <ReactMarkdown>{m.content}</ReactMarkdown>
                        
                      </div>
                    ))
                  )}

                  {loading && (
                    <div className="flex items-center space-x-2 p-3 bg-white border border-gray-200 rounded-xl mr-auto max-w-fit shadow-sm flex-shrink-0">
                      <svg className="animate-spin h-4 w-4 text-blue-500" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
                        <circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4"></circle>
                        <path className="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
                      </svg>
                      <span className="text-sm text-gray-600">La IA está respondiendo...</span>
                    </div>
                  )}

                  <div ref={messagesEndRef} />
                </div>
                </div>

                {attachedPreviews.length > 0 && (
                  <ul className="text-xs text-gray-600 mt-2">
                    {attachedPreviews.map((name, i) => (
                      <li key={i}>📄 {name}</li>
                    ))}
                  </ul>
                )}

                <div className="flex gap-2 mt-4 items-end flex-shrink-0">
                  <label className="cursor-pointer text-gray-600 hover:text-blue-600 self-center">
                    <Paperclip className="w-5 h-5" />
                    <input type="file" accept=".pdf,.txt,.doc,.docx" multiple  className="hidden" onChange={handleAttach} />
                  </label>

                  <textarea
                    value={input}
                    onChange={(e) => setInput(e.target.value)}
                    placeholder="Escribe tu pregunta..."
                    onKeyDown={(e) => {
                      if (e.key === "Enter" && !e.shiftKey) {
                        e.preventDefault();
                        handleSend();
                      }
                    }}
                    rows={1}
                    className="flex-1 resize-none rounded-xl border border-gray-300 p-3 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500 max-h-32 overflow-y-auto bg-white shadow-inner"
                    style={{ minHeight: "38px" }}
                  />

                  <Button onClick={handleSend} disabled={loading || creatingConversation || (!input.trim() && attachedFiles.length === 0 && !selectedVectorFile)} className="shadow-md">
                    {creatingConversation ? "Preparando..." : loading ? "Enviando..." : "Enviar"}
                  </Button>

                  <Button onClick={handleApply} disabled={!messages.some((m) => m.role === "assistant")} className="shadow-md">
                    Aplicar mejora
                  </Button>
                </div>
              </CardContent>
            </Card>
          </div>
        </div>
      </DialogContent>
    </Dialog>
  );
}
