// src/components/Chatbot.tsx

import React, { useState, useEffect, useRef } from 'react';
import ReactMarkdown from 'react-markdown';
import rehypeSanitize from 'rehype-sanitize';
import './Chatbot.css';

interface Message {
  text: string;
  sender: 'user' | 'bot';
}

const MAX_CHARS = 200;
// Constante para la clave del localStorage
const CHAT_HISTORY_KEY = 'chatbot-history';

const Chatbot: React.FC = () => {
  const [isOpen, setIsOpen] = useState(false);
  const [messages, setMessages] = useState<Message[]>(() => {
    try {
      // 1. Intentamos obtener el historial guardado.
      const savedHistory = localStorage.getItem(CHAT_HISTORY_KEY);
      if (savedHistory) {
        // 2. Si existe, lo parseamos y lo devolvemos para usarlo como estado inicial.
        return JSON.parse(savedHistory);
      }
    } catch (error) {
      console.error("No se pudo cargar el historial del chat desde localStorage:", error);
    }
    // 3. Si no hay nada guardado o hay un error, devolvemos el estado por defecto.
    return [{ text: '¡Hola! Soy tu asistente virtual. ¿En qué puedo ayudarte hoy?', sender: 'bot' }];
  });

  const [inputValue, setInputValue] = useState('');
  const [isLoading, setIsLoading] = useState(false);
  const messagesEndRef = useRef<null | HTMLDivElement>(null);

  // Añadimos un useEffect para guardar los mensajes.
  useEffect(() => {
    try {
      // Cada vez que el array de 'messages' cambie, lo guardamos en localStorage.
      localStorage.setItem(CHAT_HISTORY_KEY, JSON.stringify(messages));
    } catch (error) {
      console.error("No se pudo guardar el historial del chat en localStorage:", error);
    }
  }, [messages]);


  useEffect(() => {
    // Solo intentamos hacer scroll si la ventana del chat está abierta.
    if (isOpen) {
      // Usamos un pequeño retardo para asegurar que el navegador haya renderizado
      // completamente la ventana antes de intentar hacer el scroll.
      // Esto previene problemas si hay animaciones CSS.
      setTimeout(() => {
        messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });
      }, 50);
    }
  }, [messages, isOpen]);

  const toggleChat = () => setIsOpen(!isOpen);

  const handleInputChange = (event: React.ChangeEvent<HTMLInputElement>) => {
    setInputValue(event.target.value);
  };

  const handleSendMessage = async (event: React.FormEvent<HTMLFormElement>) => {
    event.preventDefault();
    if (inputValue.trim() === '' || isLoading) return;

    const userMessage: Message = { text: inputValue, sender: 'user' };
    setMessages(prev => [...prev, userMessage]);
    const messageToSend = inputValue;
    setInputValue('');
    setIsLoading(true);

    const botMessagePlaceholder: Message = { text: '', sender: 'bot' };
    setMessages(prev => [...prev, botMessagePlaceholder]);

    try {
      const response = await fetch(`${import.meta.env.VITE_API_BASE_URL}/api/chat/stream-message`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ message: messageToSend }),
      });

      if (!response.ok || !response.body) {
        throw new Error('Error en la respuesta del servidor.');
      }

      const reader = response.body.getReader();
      const decoder = new TextDecoder();
      let accumulatedResponse = ''; // Variable para acumular el texto crudo

      const readStream = async () => {
        while (true) {
          const { done, value } = await reader.read();

          if (done) {
            // El stream ha terminado, no hacemos nada más aquí.
            break;
          }

          // Acumulamos la respuesta cruda que viene del backend
          accumulatedResponse += decoder.decode(value);

          try {
            // Intentamos limpiar la respuesta acumulada
            // 1. Parseamos como si fuera un array JSON
            const parsedArray = JSON.parse(accumulatedResponse
              // Añadimos un corchete de cierre por si el stream se corta a la mitad
              .replace(/,$/, '') + ']');

            // 2. Unimos los fragmentos del array en un solo texto
            const cleanText = Array.isArray(parsedArray) ? parsedArray.join('') : accumulatedResponse;

            // 3. Actualizamos el estado con el texto limpio
            setMessages(prev => {
              const lastMessage = prev[prev.length - 1];
              const updatedLastMessage = { ...lastMessage, text: cleanText };
              return [...prev.slice(0, -1), updatedLastMessage];
            });

          } catch (e) {
            // Si hay un error de parseo (porque el JSON aún no está completo),
            // mostramos el texto sin los caracteres iniciales/finales.
            const partiallyCleanedText = accumulatedResponse
              .replace(/^\[?"|"?,"?|"?\]$/g, '')
              .replace(/","/g, '');

            setMessages(prev => {
              const lastMessage = prev[prev.length - 1];
              const updatedLastMessage = { ...lastMessage, text: partiallyCleanedText };
              return [...prev.slice(0, -1), updatedLastMessage];
            });
          }
        }
      };

      await readStream();

    } catch (error) {
      console.error("Error al conectar con la API de streaming:", error);
      const errorText = error instanceof Error ? error.message : 'Lo siento, no pude conectarme.';

      setMessages(prev => {
        const lastMessage = prev[prev.length - 1];
        const updatedLastMessage = { ...lastMessage, text: errorText };
        return [...prev.slice(0, -1), updatedLastMessage];
      });

    } finally {
      setIsLoading(false);
    }
  };

  return (
    <>
      <div className="chat-bubble" onClick={toggleChat}>
        <span>{isOpen ? 'X' : '💬'}</span>
      </div>

      {isOpen && (
        <div className="chat-window">
          <div className="chat-header">
            <span>Asistente Virtual - El Día</span>
            <button className="close-button" onClick={toggleChat}>&times;</button>
          </div>
          <div className="messages-container">
            {messages.map((msg, index) => (
              <div key={index} className={`message ${msg.sender}`}>
                <ReactMarkdown rehypePlugins={[rehypeSanitize]}>
                  {msg.text.replace(/\\n/g, "\n")}
                </ReactMarkdown>
              </div>
            ))}
            <div ref={messagesEndRef} />
          </div>
          <form className="input-form" onSubmit={handleSendMessage}>
            <div className="input-container">
              <input
                type="text"
                placeholder={isLoading ? "Esperando respuesta..." : "Escribe tu consulta..."}
                value={inputValue}
                onChange={handleInputChange}
                disabled={isLoading}
                maxLength={MAX_CHARS}
              />
              <div className="char-counter">
                {inputValue.length} / {MAX_CHARS}
              </div>
            </div>
            <button type="submit" disabled={isLoading}>
              {isLoading ? '...' : '→'}
            </button>
          </form>
        </div>
      )}
    </>
  );
};

export default Chatbot;