#Importaciones generales
import streamlit as st
import re
import io
import base64
import matplotlib.pyplot as plt
import pandas as pd
from streamlit_player import st_player  # Necesitarás instalar esta librería: pip install streamlit-player
from spacy import displacy


#Importaciones locales
#Importaciones locales de autenticación y base de datos 
from .auth import authenticate_user, register_user, get_user_role
from .database import get_student_data, store_morphosyntax_result, store_semantic_result, store_chat_history

#Importaciones locales funciones de análisis
from .morpho_analysis import generate_arc_diagram, get_repeated_words_colors, highlight_repeated_words, POS_COLORS, POS_TRANSLATIONS
from .semantic_analysis import visualize_semantic_relations, perform_semantic_analysis
from .discourse_analysis import compare_semantic_analysis, perform_discourse_analysis
from .chatbot import initialize_chatbot, get_chatbot_response

##################################################################################################
def login_register_page():
    st.title("AIdeaText")

    # Dividir la pantalla en dos columnas
    left_column, right_column = st.columns([1, 3])  # 25% izquierda, 75% derecha

    # Sección izquierda para login y registro
    with left_column:
        tab1, tab2 = st.tabs(["Iniciar Sesión", "Registrarse"])
        
        with tab1:
            login_form()
        
        with tab2:
            register_form()

    # Sección derecha para videos de YouTube
    with right_column:
        st.header("Videos: pitch, demos, entrevistas, otros")
        
        # Diccionario de videos de YouTube con títulos amigables
        videos = {
            "Intro AideaText": "https://www.youtube.com/watch?v=UA-md1VxaRc",
            "Pitch que facilitó acceder a la segunda fase de IFE Explora del TEC de Monterrey": "https://www.youtube.com/watch?v=Fqi4Di_Rj_s",
            "Entrevista con el doctor Guillermo Ruíz, EduMate Lima Perú" : "https://www.youtube.com/watch?v=_ch8cRja3oc",
            "Demo versión desktop de AIdeaText": "https://www.youtube.com/watch?v=nP6eXbog-ZY"
        }
        
        # Selector de video
        video_titles = list(videos.keys())
        if video_titles:
            selected_title = st.selectbox("Selecciona un video tutorial:", video_titles)
            
            # Obtener la URL correspondiente al título seleccionado
            if selected_title in videos:
                selected_video = videos[selected_title]
                
                # Reproductor de YouTube
                try:
                    st_player(selected_video)
                except Exception as e:
                    st.error(f"Error al cargar el video: {str(e)}")
            else:
                st.warning("El video seleccionado no está disponible.")
        else:
            st.warning("No hay videos disponibles para mostrar.")

        # Información adicional
        st.markdown("""
        ## Novedades de la versión actual
        - Nueva función de análisis semántico
        - Soporte para múltiples idiomas
        - Interfaz mejorada para una mejor experiencia de usuario
        """)

##################################################################################################
def login_form():
    username = st.text_input("Usuario")
    password = st.text_input("Contraseña", type='password')
    captcha_answer = st.text_input("Captcha: ¿Cuánto es 2 + 3?")
    
    if st.button("Iniciar Sesión"):
        if captcha_answer == "5":
            if authenticate_user(username, password):
                st.success(f"Bienvenido, {username}!")
                st.session_state.logged_in = True
                st.session_state.username = username
                st.session_state.role = get_user_role(username)
                st.experimental_rerun()
            else:
                st.error("Usuario o contraseña incorrectos")
        else:
            st.error("Captcha incorrecto")

##################################################################################################
def register_form():
    new_username = st.text_input("Nuevo Usuario")
    new_password = st.text_input("Nueva Contraseña", type='password')
    carrera = st.text_input("Carrera")
    captcha_answer = st.text_input("Captcha: ¿Cuánto es 3 + 4?")
    
    if st.button("Registrarse"):
        if captcha_answer == "7":
            additional_info = {'carrera': carrera}
            if register_user(new_username, new_password, additional_info):
                st.success("Registro exitoso. Por favor, inicia sesión.")
            else:
                st.error("El usuario ya existe o ocurrió un error durante el registro")
        else:
            st.error("Captcha incorrecto")

##################################################################################################
def display_chat_interface():
    st.markdown("### Chat con AIdeaText")

    if 'chat_history' not in st.session_state:
        st.session_state.chat_history = []

    for i, (role, text) in enumerate(st.session_state.chat_history):
        if role == "user":
            st.text_area(f"Tú:", value=text, height=50, key=f"user_message_{i}", disabled=True)
        else:
            st.text_area(f"AIdeaText:", value=text, height=50, key=f"bot_message_{i}", disabled=True)

    user_input = st.text_input("Escribe tu mensaje aquí:")

    if st.button("Enviar"):
        if user_input:
            st.session_state.chat_history.append(("user", user_input))
            response = get_chatbot_response(user_input)
            st.session_state.chat_history.append(("bot", response))
            st.experimental_rerun()

##################################################################################################
def display_student_progress(username, lang_code='es'):
    student_data = get_student_data(username)
    
    if student_data is None:
        st.warning("No se encontraron datos para este estudiante.")
        st.info("Intenta realizar algunos análisis de texto primero.")
        return

    st.title(f"Progreso de {username}")

    if student_data['entries_count'] > 0:
        if 'word_count' in student_data and student_data['word_count']:
            st.subheader("Total de palabras por categoría gramatical")
            
            df = pd.DataFrame(list(student_data['word_count'].items()), columns=['category', 'count'])
            df['label'] = df.apply(lambda x: f"{POS_TRANSLATIONS[lang_code].get(x['category'], x['category'])}", axis=1)
            
            df = df.sort_values('count', ascending=False)
            
            fig, ax = plt.subplots(figsize=(12, 6))
            bars = ax.bar(df['label'], df['count'], color=[POS_COLORS.get(cat, '#CCCCCC') for cat in df['category']])
            
            ax.set_xlabel('Categoría Gramatical')
            ax.set_ylabel('Cantidad de Palabras')
            ax.set_title('Total de palabras por categoría gramatical')
            plt.xticks(rotation=45, ha='right')
            
            for bar in bars:
                height = bar.get_height()
                ax.text(bar.get_x() + bar.get_width()/2., height,
                        f'{height}',
                        ha='center', va='bottom')
            
            plt.tight_layout()
            
            buf = io.BytesIO()
            fig.savefig(buf, format='png')
            buf.seek(0)
            st.image(buf, use_column_width=True)
        else:
            st.info("No hay datos de conteo de palabras disponibles.")    
        
        st.header("Diagramas de Arco")
        with st.expander("Ver todos los Diagramas de Arco"):
            for i, entry in enumerate(student_data['entries']):
                if 'arc_diagrams' in entry and entry['arc_diagrams']:
                    st.subheader(f"Entrada {i+1} - {entry['timestamp']}")
                    st.write(entry['arc_diagrams'][0], unsafe_allow_html=True)
        
        st.header("Diagramas de Red")
        with st.expander("Ver todos los Diagramas de Red"):
            for i, entry in enumerate(student_data['entries']):
                if 'network_diagram' in entry and entry['network_diagram']:
                    st.subheader(f"Entrada {i+1} - {entry['timestamp']}")
                    try:
                        image_bytes = base64.b64decode(entry['network_diagram'])
                        st.image(image_bytes)
                    except Exception as e:
                        st.error(f"Error al mostrar el diagrama de red: {str(e)}")
    else:
        st.warning("No se encontraron entradas para este estudiante.")
        st.info("Intenta realizar algunos análisis de texto primero.")

##################################################################################################

def display_morphosyntax_analysis_interface(nlp_models, lang_code):
    translations = {
        'es': {
            'title': "AIdeaText - Análisis morfológico y sintáctico",
            'input_label': "Ingrese un texto para analizar (máx. 5,000 palabras):",
            'input_placeholder': "El objetivo de esta aplicación es que mejore sus habilidades de redacción...",  
            'analyze_button': "Analizar texto",
            'repeated_words': "Palabras repetidas",
            'legend': "Leyenda: Categorías gramaticales",
            'arc_diagram': "Análisis sintáctico: Diagrama de arco",
            'sentence': "Oración"
        },
        'en': {
            'title': "AIdeaText - Morphological and Syntactic Analysis",
            'input_label': "Enter a text to analyze (max 5,000 words):",
            'input_placeholder': "The goal of this app is for you to improve your writing skills...",
            'analyze_button': "Analyze text",
            'repeated_words': "Repeated words",
            'legend': "Legend: Grammatical categories",
            'arc_diagram': "Syntactic analysis: Arc diagram",
            'sentence': "Sentence"
        },
        'fr': {
            'title': "AIdeaText - Analyse morphologique et syntaxique",
            'input_label': "Entrez un texte à analyser (max 5 000 mots) :",
            'input_placeholder': "Le but de cette application est d'améliorer vos compétences en rédaction...",
            'analyze_button': "Analyser le texte",
            'repeated_words': "Mots répétés",
            'legend': "Légende : Catégories grammaticales",
            'arc_diagram': "Analyse syntaxique : Diagramme en arc",
            'sentence': "Phrase"
        }
    }

    t = translations[lang_code]

    input_key = f"morphosyntax_input_{lang_code}"

    # Inicializar la clave en session_state si no existe
    if input_key not in st.session_state:
        st.session_state[input_key] = ""

    # Función para actualizar el estado del input
    def update_input():
        st.session_state[input_key] = st.session_state[f"text_area_{lang_code}"]

    sentence_input = st.text_area(
        t['input_label'],
        height=150,
        placeholder=t['input_placeholder'],
        value=st.session_state[input_key],
        key=f"text_area_{lang_code}",
        on_change=update_input
    )

    if st.button(t['analyze_button'], key=f"analyze_button_{lang_code}"):
        current_input = st.session_state[input_key]
        if current_input:
            doc = nlp_models[lang_code](current_input)
            
            word_colors = get_repeated_words_colors(doc)
            
            with st.expander(t['repeated_words'], expanded=True):
                highlighted_text = highlight_repeated_words(doc, word_colors)
                st.markdown(highlighted_text, unsafe_allow_html=True)
            
            st.markdown(f"##### {t['legend']}")
            legend_html = "<div style='display: flex; flex-wrap: wrap;'>"
            for pos, color in POS_COLORS.items():
                if pos in POS_TRANSLATIONS[lang_code]:
                    legend_html += f"<div style='margin-right: 10px;'><span style='background-color: {color}; padding: 2px 5px;'>{POS_TRANSLATIONS[lang_code][pos]}</span></div>"
            legend_html += "</div>"
            st.markdown(legend_html, unsafe_allow_html=True)
            
            with st.expander(t['arc_diagram'], expanded=True):
                sentences = list(doc.sents)
                arc_diagrams = []
                for i, sent in enumerate(sentences):
                    st.subheader(f"{t['sentence']} {i+1}")
                    html = displacy.render(sent, style="dep", options={"distance": 100})
                    html = html.replace('height="375"', 'height="200"')
                    html = re.sub(r'<svg[^>]*>', lambda m: m.group(0).replace('height="450"', 'height="300"'), html)
                    html = re.sub(r'<g [^>]*transform="translate\((\d+),(\d+)\)"', lambda m: f'<g transform="translate({m.group(1)},50)"', html)
                    st.write(html, unsafe_allow_html=True)
                    arc_diagrams.append(html)
            
            if store_morphosyntax_result(
                st.session_state.username,
                current_input,
                word_colors,
                arc_diagrams,
            ):
                st.success("Análisis guardado correctamente.")
            else:
                st.error("Hubo un problema al guardar el análisis. Por favor, inténtelo de nuevo.")
        else:
            st.warning("Por favor, ingrese un texto para analizar.")

###############################################################################################################
def display_semantic_analysis_interface(nlp_models, lang_code):
    translations = {
        'es': {
            'title': "AIdeaText - Análisis semántico",
            'file_uploader': "Cargar archivo de texto",
            'analyze_button': "Analizar texto",
            'semantic_relations': "Relaciones Semánticas Relevantes",
        },
        'en': {
            'title': "AIdeaText - Semantic Analysis",
            'file_uploader': "Upload text file",
            'analyze_button': "Analyze text",
            'semantic_relations': "Relevant Semantic Relations",
        },
        'fr': {
            'title': "AIdeaText - Analyse sémantique",
            'file_uploader': "Télécharger le fichier texte",
            'analyze_button': "Analyser le texte",
            'semantic_relations': "Relations Sémantiques Pertinentes",
        }
    }

    t = translations[lang_code]

    st.header(t['title'])

    uploaded_file = st.file_uploader(t['file_uploader'], type=['txt'])

    if uploaded_file is not None:
        text_content = uploaded_file.getvalue().decode('utf-8')

        if st.button(t['analyze_button']):
            relations_graph = perform_semantic_analysis(text_content, nlp_models[lang_code], lang_code)

            with st.expander(t['semantic_relations'], expanded=True):
                st.pyplot(relations_graph)

##################################################################################################

def display_discourse_analysis_interface(nlp_models, lang_code):
    translations = {
        'es': {
            'title': "AIdeaText - Análisis del discurso",
            'file_uploader1': "Cargar archivo de texto 1 (Patrón)",
            'file_uploader2': "Cargar archivo de texto 2 (Comparación)",
            'analyze_button': "Analizar textos",
            'comparison': "Comparación de Relaciones Semánticas",
        },
        'en': {
            'title': "AIdeaText - Discourse Analysis",
            'file_uploader1': "Upload text file 1 (Pattern)",
            'file_uploader2': "Upload text file 2 (Comparison)",
            'analyze_button': "Analyze texts",
            'comparison': "Comparison of Semantic Relations",
        },
        'fr': {
            'title': "AIdeaText - Analyse du discours",
            'file_uploader1': "Télécharger le fichier texte 1 (Modèle)",
            'file_uploader2': "Télécharger le fichier texte 2 (Comparaison)",
            'analyze_button': "Analyser les textes",
            'comparison': "Comparaison des Relations Sémantiques",
        }
    }

    t = translations[lang_code]

    st.header(t['title'])

    col1, col2 = st.columns(2)

    with col1:
        uploaded_file1 = st.file_uploader(t['file_uploader1'], type=['txt'])

    with col2:
        uploaded_file2 = st.file_uploader(t['file_uploader2'], type=['txt'])

    if uploaded_file1 is not None and uploaded_file2 is not None:
        text_content1 = uploaded_file1.getvalue().decode('utf-8')
        text_content2 = uploaded_file2.getvalue().decode('utf-8')

        if st.button(t['analyze_button']):
            graph1, graph2 = perform_discourse_analysis(text_content1, text_content2, nlp_models[lang_code], lang_code)

            st.subheader(t['comparison'])
            
            col1, col2 = st.columns(2)
            
            with col1:
                st.pyplot(graph1)
            
            with col2:
                st.pyplot(graph2)

##################################################################################################
def display_chatbot_interface(lang_code):
    translations = {
        'es': {
            'title': "AIdeaText - Chatbot Multilingüe",
            'input_placeholder': "Escribe tu mensaje aquí...",
            'send_button': "Enviar",
            'initial_message': "¡Hola! ¿En qué puedo ayudarte hoy?"
        },
        'en': {
            'title': "AIdeaText - Multilingual Chatbot",
            'input_placeholder': "Type your message here...",
            'send_button': "Send",
            'initial_message': "Hello! How can I assist you today?"
        },
        'fr': {
            'title': "AIdeaText - Chatbot Multilingue",
            'input_placeholder': "Écrivez votre message ici...",
            'send_button': "Envoyer",
            'initial_message': "Bonjour! Comment puis-je vous aider aujourd'hui?"
        }
    }

    t = translations[lang_code]

    st.header(t['title'])

    if 'chatbot' not in st.session_state:
        st.session_state.chatbot = initialize_chatbot()

    if 'messages' not in st.session_state:
        st.session_state.messages = [{"role": "assistant", "content": t['initial_message']}]

    # Mostrar mensajes previos
    for message in st.session_state.messages:
        with st.chat_message(message["role"]):
            st.markdown(message["content"])

    # Input del usuario
    if prompt := st.chat_input(t['input_placeholder']):
        st.session_state.messages.append({"role": "user", "content": prompt})
        with st.chat_message("user"):
            st.markdown(prompt)

        with st.chat_message("assistant"):
            message_placeholder = st.empty()
            full_response = ""
            for response in get_chatbot_response(st.session_state.chatbot, prompt, lang_code):
                full_response += response + " "
                message_placeholder.markdown(full_response + "▌")
            message_placeholder.markdown(full_response)
        st.session_state.messages.append({"role": "assistant", "content": full_response})

        # Guardar la conversación en la base de datos
        store_chat_history(st.session_state.username, st.session_state.messages)