import { useState, useEffect } from "react";
import { FeedbackButton } from "./FeedbackButton";
import { PDFModal } from "./PDFModal";
import Markdown from "react-markdown";
import rehypeRaw from "rehype-raw";
import { SSE } from "sse.js";

export { ChatMessage };

interface ChatMessageProps {
  isUser: boolean;
  content: string;
  event: CallableFunction;
  conversationId: string;
  setReceivingMsg: (receiving: boolean) => void;
  userAvatar: string;
  botAvatar: string;
  onFeedback?: (key: string, rating: string) => Promise<void>;
}

function ChatMessage({
  isUser,
  content,
  event,
  conversationId,
  setReceivingMsg,
  userAvatar,
  botAvatar,
  onFeedback
}: ChatMessageProps) {
  const [buff, setBuff] = useState("");
  const [responseId, setResponseId] = useState("");
  const [loading, setLoading] = useState(false);

  const [images, setImages] = useState<string[]>([]);
  const [currentImageIndex, setCurrentImageIndex] = useState(0);
  const [acceptFeedback, setAcceptFeedback] = useState(false);
  const [streamIndex, setStreamIndex] = useState(0);
  const [fullResponse, setFullResponse] = useState("");
  const [pendingReferences, setPendingReferences] = useState<Array<any>>([]);
  const [streamingComplete, setStreamingComplete] = useState(false);
  
  const [pdfModal, setPdfModal] = useState({
    isOpen: false,
    filename: '',
    page: undefined as number | undefined
  });

 

  const closePdfModal = () => {
    setPdfModal({
      isOpen: false,
      filename: '',
      page: undefined
    });
  };

  useEffect(() => {
    const handleKeyDown = (event: KeyboardEvent) => {
      if (event.key === 'Escape' && pdfModal.isOpen) {
        closePdfModal();
      }
    };

    if (pdfModal.isOpen) {
      document.addEventListener('keydown', handleKeyDown);
      return () => document.removeEventListener('keydown', handleKeyDown);
    }
  }, [pdfModal.isOpen]);

  const nextImage = () => {
    if (currentImageIndex < images.length - 1) {
      setCurrentImageIndex((prev) => prev + 1);
    }
  };

  const prevImage = () => {
    if (currentImageIndex > 0) {
      setCurrentImageIndex((prev) => prev - 1);
    }
  };

  useEffect(() => {
    if (fullResponse && streamIndex < fullResponse.length) {
      setLoading(false);

      const timer = setTimeout(() => {
        setBuff((prev) => prev + fullResponse[streamIndex]);
        setStreamIndex((prev) => prev + 1);
        event();
      }, 3);

      return () => clearTimeout(timer);
    } else if (fullResponse && streamIndex === fullResponse.length) {
      setReceivingMsg(false);
      setStreamingComplete(true);
      setBuff(fullResponse);
    }
  }, [fullResponse, streamIndex]);

  async function getStream() {
    const payload = JSON.stringify({
      prompt: content,
      conversation_id: conversationId,
    });

    const url = "/api/v1/message?stream=True";
    const eventSource = new SSE(url, {
      withCredentials: true,
      headers: { "Content-Type": "application/json" },
      payload: payload,
    });

    eventSource.onmessage = async (event) => {
      console.log(event.data);
      const ResponseChunk = JSON.parse(event.data);

      if (ResponseChunk["type"] === "text") {
        const content = ResponseChunk["content"];
        setFullResponse((prev) => prev + content);
      } else if (ResponseChunk["type"] === "reference") {
        setPendingReferences(ResponseChunk["content"]);
      } else if (ResponseChunk["type"] === "end") {
        setResponseId(ResponseChunk["content"]);
        eventSource.close();
      } else if (ResponseChunk["type"] === "image") {
        const newImages = ResponseChunk.content.slice(0, 3);
        setImages((prev) => {
          const combinedImages = [...prev, ...newImages];
          return combinedImages.slice(0, 3);
        });
      } else if (ResponseChunk["type"] == "tool") {
        setAcceptFeedback(true);
      } else if (ResponseChunk["type"] === "error") {
        setFullResponse((prev) => prev + "\n\n" + ResponseChunk["content"]);
        eventSource.close();
      }
    };
    eventSource.onerror = async (e) => {
      console.log("error" + e);
      setReceivingMsg(false);
      setLoading(false);
      eventSource.close();
    };
  }

  useEffect(() => {
    if (!isUser) {
      setLoading(true);
      setReceivingMsg(true);
      getStream();
    } else {
      setBuff(content);
      event();
    }
  }, []);

  const Metadata = ({ metadatas }: { metadatas: any[] }) => {
  const [isExpanded, setIsExpanded] = useState(false);
  
  if (!metadatas || metadatas.length === 0) return null;
  
  // Mapeo de archivos a URLs públicas (mismo que en el backend)
  const PDF_PUBLIC_URLS: { [key: string]: string } = {
    "Disposiciones de carácter general aplicables a las casas de bolsa.pdf": "https://www.cnbv.gob.mx/Normatividad/Disposiciones%20de%20car%C3%A1cter%20general%20aplicables%20a%20las%20casas%20de%20bolsa.pdf",
    "Disposiciones de carácter general aplicables a las instituciones de crédito.pdf": "https://www.cnbv.gob.mx/Normatividad/Disposiciones%20de%20car%C3%A1cter%20general%20aplicables%20a%20las%20instituciones%20de%20cr%C3%A9dito.pdf",
    "Disposiciones de carácter general aplicables a las sociedades controladoras de grupos financieros y subcontroladoras que regulan las materias que corresponden de manera conjunta a las Comisio.pdf": "https://www.cnbv.gob.mx/Normatividad/Disposiciones%20de%20car%C3%A1cter%20general%20aplicables%20a%20las%20sociedades%20controladoras%20de%20grupos%20financieros%20y%20subcontroladoras%20que%20regulan%20las%20materias%20que%20corresponden%20de%20manera%20conjunta%20a%20las%20Comisiones%20Nacionales%20Supervisoras.pdf",
    "Disposiciones de carácter general aplicables a los fondos de inversión y a las personas que les prestan servicios.pdf": "https://www.cnbv.gob.mx/Normatividad/Disposiciones%20de%20car%C3%A1cter%20general%20aplicables%20a%20los%20fondos%20de%20inversi%C3%B3n%20y%20a%20las%20personas%20que%20les%20prestan%20servicios.pdf",
    "Ley para la Transparencia y Ordenamiento de los Servicios Financieros.pdf": "https://www.cnbv.gob.mx/Normatividad/Ley%20para%20la%20Transparencia%20y%20Ordenamiento%20de%20los%20Servicios%20Financieros.pdf",
    "circular_servicios_de_inversion.pdf": "https://www.cnbv.gob.mx/Normatividad/Disposiciones%20de%20car%C3%A1cter%20general%20aplicables%20a%20las%20entidades%20financieras%20y%20dem%C3%A1s%20personas%20que%20proporcionen%20servicios%20de.pdf",
    "circular_unica_de_auditores_externos.pdf": "https://www.cnbv.gob.mx/Normatividad/Disposiciones%20de%20car%C3%A1cter%20general%20que%20establecen%20los%20requisitos%20que%20deber%C3%A1n%20cumplir%20los%20auditores%20y%20otros%20profesionales%20que.pdf",
    "ley_de_instituciones_de_Credito.pdf": "https://www.cnbv.gob.mx/Normatividad/Ley%20de%20Instituciones%20de%20Cr%C3%A9dito.pdf",
    "circular_13_2007.pdf": "https://www.banxico.org.mx/marco-normativo/normativa-emitida-por-el-banco-de-mexico/circular-13-2007/cobro-intereses-por-adelantad.html",
    "circular_13_2011.pdf": "https://www.banxico.org.mx/marco-normativo/normativa-emitida-por-el-banco-de-mexico/circular-13-2011/%7BBA4CBC28-A468-16C9-6F17-9EA9D7B03318%7D.pdf",
    "circular_14_2007.pdf": "https://www.banxico.org.mx/marco-normativo/normativa-emitida-por-el-banco-de-mexico/circular-14-2007/%7BFB726B6B-D523-56F5-F9B1-BE5B3B95A504%7D.pdf",
    "circular_17_2014.pdf": "https://www.banxico.org.mx/marco-normativo/normativa-emitida-por-el-banco-de-mexico/circular-17-2014/%7BF36CEF03-9441-2DBE-082C-0DF274903782%7D.pdf",
    "circular_1_2005.pdf": "https://www.banxico.org.mx/marco-normativo/normativa-emitida-por-el-banco-de-mexico/circular-1-2005/%7B5CA4BA75-FEA8-199C-F129-E8E6A73E84F3%7D.pdf",
    "circular_21_2009.pdf": "https://www.banxico.org.mx/marco-normativo/normativa-emitida-por-el-banco-de-mexico/circular-21-2009/%7B29285862-EDE0-567A-BAFB-D261406641A3%7D.pdf",
    "circular_22_2008.pdf": "https://www.banxico.org.mx/marco-normativo/normativa-emitida-por-el-banco-de-mexico/circular-22-2008/%7BF15C8A26-C92E-BE2B-9344-51EDAA3C9B68%7D.pdf",
    "circular_22_2010.pdf": "https://www.banxico.org.mx/marco-normativo/normativa-emitida-por-el-banco-de-mexico/circular-22-2010/%7B0D531F59-1001-4D67-D7B4-D5854DD07A58%7D.pdf",
    "circular_27_2008.pdf": "https://www.banxico.org.mx/marco-normativo/normativa-emitida-por-el-banco-de-mexico/circular-27-2008/%7BBC4333FE-070F-E727-199E-CA6BCF2CBA66%7D.pdf",
    "circular_34_2010.pdf": "https://www.banxico.org.mx/marco-normativo/normativa-emitida-por-el-banco-de-mexico/circular-34-2010/%7B0C55B906-6DB4-6B88-FED0-67987E9FB3CC%7D.pdf",
    "circular_35_2010.pdf": "https://www.banxico.org.mx/marco-normativo/normativa-emitida-por-el-banco-de-mexico/circular-35-2010/%7B74C5641C-ED98-53C7-F08B-A3C7BAE0D480%7D.pdf",
    "circular_36_2010.pdf": "https://www.banxico.org.mx/marco-normativo/normativa-emitida-por-el-banco-de-mexico/circular-36-2010/%7B26C55DE6-CC3A-3368-34FC-1A6C50B11130%7D.pdf",
    "circular_3_2012.pdf": "https://www.banxico.org.mx/marco-normativo/normativa-emitida-por-el-banco-de-mexico/circular-3-2012/%7B4E0281A4-7AD8-1462-BC79-7F2925F3171D%7D.pdf",
    "circular_4_2012.pdf": "https://www.banxico.org.mx/marco-normativo/normativa-emitida-por-el-banco-de-mexico/circular-4-2012/%7B97C62974-1C94-19AE-AB5A-D0D949A36247%7D.pdf",
    "circular_unica_de_condusef.pdf": "https://www.condusef.gob.mx/documentos/marco_legal/disposiciones-transparencia-if-sofom.pdf",
    "ley_para_regular_las_sociedades_de_informacion_crediticia.pdf": "https://www.condusef.gob.mx/documentos/marco_legal/disposiciones-transparencia-if-sofom.pdf",
    "ley_federal_de_proteccion_de_datos_personales_en_posesion_de_los_particulares.pdf": "https://www.diputados.gob.mx/LeyesBiblio/pdf/LFPDPPP.pdf",
    "reglamento_de_la_ley_federal_de_proteccion_de_datos_personales_en_posesion_de_los_particulares.pdf": "https://www.diputados.gob.mx/LeyesBiblio/regley/Reg_LFPDPPP.pdf",
    "Modificaciones Recursos Procedencia Ilícita jul 25 PLD.pdf": "https://gfbanorte.sharepoint.com/:w:/r/sites/Formatosyplantillas/Documentos%20compartidos/Otros/Modificaciones%20Recursos%20Procedencia%20Il%C3%ADcita%20jul%2025%20PLD.docx?d=w6a941e9e2c26403ea41c12de35536516&csf=1&web=1&e=EHtc9b",
  };

  const handlePdfClick = (fileName: string, page?: number) => {
    const publicUrl = PDF_PUBLIC_URLS[fileName];
    
    if (publicUrl) {
      // Abrir PDF público directamente
      let finalUrl = publicUrl;
      if (page) {
        finalUrl += `#page=${page}`;
      }
      window.open(finalUrl, '_blank');
    } else {
      // Fallback: usar tu modal para PDFs locales
      setPdfModal({
        isOpen: true,
        filename: fileName,
        page: page
      });
    }
  };
  
  return (
    <div className="mt-4">
      <button 
        onClick={() => setIsExpanded(!isExpanded)}
        className="inline-flex items-center px-4 py-2 border border-gray-300 rounded-lg bg-gray-50 hover:bg-gray-100 transition-colors"
      >
        <span className="font-medium text-gray-700 mr-2">Fuentes</span>
        <span className="text-gray-500">
          {isExpanded ? '▲' : '▼'}
        </span>
      </button>
      
      {isExpanded && (
        <div className="mt-3 border border-gray-300 rounded-lg bg-gray-50 p-4">
          <div className="space-y-2">
            {metadatas.map((metadata, index) => {
              const fileName = metadata.file_name || metadata.file || 'Documento';
              const page = metadata.page;
              const displayText = page ? `${fileName} - Página ${page}` : fileName;
              const isPublic = PDF_PUBLIC_URLS[fileName];
              
              return (
                <div key={index} className="flex items-start space-x-2 text-sm">
                  <span className="text-gray-400 mt-1">
                    {isPublic ? '🌐' : '📄'}
                  </span>
                  <button
                    onClick={() => handlePdfClick(fileName, page)}
                    className="text-blue-600 hover:text-blue-800 hover:underline cursor-pointer text-left flex items-center"
                    title={isPublic ? 'Documento público - Se abrirá en nueva pestaña' : 'Documento local'}
                  >
                    {displayText}
                    {isPublic && (
                      <span className="ml-1 text-xs text-gray-500">↗</span>
                    )}
                  </button>
                </div>
              );
            })}
          </div>
        </div>
      )}
    </div>
  );
};

  const ImageViewer = () => {
    if (images.length === 0) return null;

    return (
      <div className="mt-5 space-y-4">
        <div className="relative">
          <img
            src={images[currentImageIndex]}
            alt={`Generated image ${currentImageIndex + 1}`}
            className="w-full h-auto rounded-lg"
          />
          <div className="flex justify-between items-center mt-4">
            <button
              onClick={prevImage}
              disabled={currentImageIndex === 0}
              className={`px-4 py-2 rounded ${
                currentImageIndex === 0
                  ? "text-gray-400 cursor-not-allowed"
                  : "text-gray-700 hover:bg-gray-100"
              }`}
            >
              ←
            </button>
            <button
              onClick={nextImage}
              disabled={currentImageIndex === images.length - 1}
              className={`px-4 py-2 rounded ${
                currentImageIndex === images.length - 1
                  ? "text-gray-400 cursor-not-allowed"
                  : "text-gray-700 hover:bg-gray-100"
              }`}
            >
              →
            </button>
          </div>
          <span className="text-sm text-gray-600 mt-2 block text-center">
            Imagen {currentImageIndex + 1} de {images.length}
          </span>
        </div>
      </div>
    );
  };

  return (
    <>
      {isUser ? (
        <div className="m-5 mr-5 flex flex-row-reverse items-start space-x-4">
          <div className="avatar placeholder mx-4 w-14 -mt-1">
            <img src={userAvatar} alt="user avatar icon" />
          </div>
          <div className="inline-block max-w-[82%] 2xl:max-w-[88%]">
            <div className="border border-slate-400 rounded-3xl bg-white p-4 text-gray-500">
              <div className="whitespace-pre-wrap text-left">
                {loading && (
                  <span className="loading loading-dots loading-md"></span>
                )}
                <Markdown rehypePlugins={[rehypeRaw]}>{buff}</Markdown>
              </div>
            </div>
          </div>
        </div>
      ) : (
        <div className="m-5 flex items-start space-x-4 w-full">
          <div className="avatar placeholder mx-4 w-14 -mt-1 mr-2">
            <img src={botAvatar} alt="bot avatar icon" />
          </div>
          <div className="inline-block max-w-[82%] 2xl:max-w-[88%]">
            <div className="border-2 border-red-500 rounded-3xl bg-white p-4 text-gray-500 pl-6">
              <div className="flex flex-col items-start">
                <div className="text-left w-full">
                  {loading && (
                    <span className="loading loading-dots loading-md"></span>
                  )}
                  <Markdown
                    rehypePlugins={[rehypeRaw]}
                    components={{
                      h1: ({ ...props }) => (
                        <h1 className="text-2xl font-bold mb-4" {...props} />
                      ),
                      h2: ({ ...props }) => (
                        <h2 className="text-xl font-bold mb-3" {...props} />
                      ),
                      h3: ({ ...props }) => (
                        <h3 className="text-lg font-bold mb-2" {...props} />
                      ),
                      p: ({ ...props }) => <p className="mb-4" {...props} />,
                      ul: ({ ...props }) => (
                        <ul
                          className="list-disc pl-6 mb-4 space-y-2"
                          {...props}
                        />
                      ),
                      ol: ({ ...props }) => (
                        <ol
                          className="list-decimal pl-6 mb-4 space-y-2"
                          {...props}
                        />
                      ),
                      li: ({ ...props }) => <li className="mb-1" {...props} />,
                      a: ({ ...props }) => (
                        <a
                          className="text-blue-600 underline hover:text-blue-800"
                          {...props}
                        />
                      ),
                      strong: ({ ...props }) => (
                        <strong className="font-bold" {...props} />
                      ),
                    }}
                  >
                    {buff}
                  </Markdown>
                  {pendingReferences.length > 0 && <Metadata metadatas={pendingReferences} />}
                  <ImageViewer />
                </div>
                {streamingComplete && acceptFeedback && onFeedback && (
                  <FeedbackButton messageKey={responseId} onFeedback={onFeedback} />
                )}
              </div>
            </div>
          </div>
        </div>
      )}
      
      <PDFModal
        isOpen={pdfModal.isOpen}
        onClose={closePdfModal}
        filename={pdfModal.filename}
        page={pdfModal.page}
      />
    </>
  );
}