import gradio as gr
import logging

# Ipotizziamo che tu abbia queste funzioni nel tuo progetto:
# - list_databases(), create_database(), modify_database(), delete_database()...
# - list_indexed_files(), upload_and_index(), delete_file_from_database(), etc.
# - search_documents(), list_indexed_documents()...
#
# Se hanno nomi o posizioni diverse, adatta gli import di conseguenza
from app.document_handling import (
    list_databases,
    create_database,
    modify_database,
    delete_database,
    upload_and_index,
    list_indexed_files,
    delete_file_from_database,
    list_indexed_documents,
    search_documents,
)
from app.llm_handling import answer_question
from app.logging_config import configure_logging

configure_logging()

def update_dropdowns():
    """Aggiorna tutti i dropdown con la lista aggiornata dei database."""
    databases = list_databases()
    # Ritorniamo 6 update() perché nel codice ci sono 6 dropdown da sincronizzare
    return [gr.update(choices=databases) for _ in range(6)]

def extract_text_from_files(files):
    """Estrae e concatena il testo da PDF, DOCX e TXT."""
    text = ""
    for file in files:
        try:
            if file.name.endswith('.pdf'):
                text += extract_text_from_pdf(file.name)   # Definita in document_handling
            elif file.name.endswith('.docx'):
                text += extract_text_from_docx(file.name)  # Definita in document_handling
            else:
                with open(file.name, 'r', encoding='utf-8') as f:
                    text += f.read()
        except Exception as e:
            logging.error(f"Errore durante la lettura del file {file.name}: {e}")
    return text


with gr.Blocks() as rag_chatbot:
    gr.Markdown("# Chatbot basato su RAG")
    
    databases = list_databases()

    # Questi State() servono per la gestione dei dropdown.  
    # Se non ti servono come stati separati, puoi anche rimuoverli.
    db_name_upload = gr.State()
    db_name_list = gr.State()
    db_name_chat = gr.State()
    db_name_new = gr.State()
    modify_db_old_name = gr.State()
    delete_db_dropdown = gr.State()

    # =============================================
    #                 TAB: Chatbot
    # =============================================
    with gr.Tab("Chatbot"):
        with gr.Row():
            with gr.Column(scale=2):
                # Dropdown per selezionare il DB
                db_name_chat = gr.Dropdown(
                    choices=databases,
                    label="Seleziona Database",
                    value="default_db"
                )

                # Chatbot component
                chatbot = gr.Chatbot(label="Conversazione", type="messages")
                
                # Input domanda
                question_input = gr.Textbox(
                    label="Fai una domanda",
                    placeholder="Scrivi qui la tua domanda...",
                    lines=2
                )
               # Bottoni azione
                with gr.Row():
                    ask_button = gr.Button("Invia")
                    clear_button = gr.Button("Pulisci Chat") 
                
                # File upload con dimensioni ridotte
                with gr.Row():
                    file_input = gr.File(
                        label="Carica PDF/Docx/TXT per la conversazione", 
                        file_types=[".pdf", ".docx", ".txt"], 
                        file_count="multiple",
                        height="100px",  # Altezza ridotta
                        scale=3  # Riduce la larghezza relativa
                    )
                    upload_button = gr.Button("Carica Documenti", scale=1)
                
                

        # Stato chat
        chat_state = gr.State([])

        # ----------------------
        #  FUNZIONI DI CALLBACK
        # ----------------------
        def chat_upload_and_respond(files, chat_history, db_name):
            # Se chat_history è None, inizializziamo
            if chat_history is None:
                chat_history = []
            
            # Estrai il testo dai file
            text = extract_text_from_files(files)
            
            # Aggiungo un messaggio "assistant" che mostra il testo caricato
            chat_history.append({
                "role": "assistant",
                "content": f"📄 Contenuto dei documenti caricati:\n{text}"
            })
            
            return chat_history

        def respond(message, chat_history, db_name):
            if chat_history is None:
                chat_history = []

            # `answer_question` restituisce due messaggi (user + assistant) in lista
            new_messages = answer_question(message, db_name)

            # Li aggiungiamo in coda alla history
            chat_history.extend(new_messages)

            # Ritorniamo l'input svuotato (per pulire il Textbox) e la nuova history
            return "", chat_history

        def clear_chat():
            # Svuota la chat
            return [], []

        # ------------------
        #   EVENTI BOTTONE
        # ------------------
        upload_button.click(
            fn=chat_upload_and_respond,
            inputs=[file_input, chat_state, db_name_chat],
            outputs=chatbot
        )

        ask_button.click(
            fn=respond,
            inputs=[question_input, chat_state, db_name_chat],
            outputs=[question_input, chatbot]
        )

        clear_button.click(
            fn=clear_chat,
            outputs=[chatbot, chat_state]
        )


    # =============================================
    #            TAB: Gestione Database
    # =============================================
    with gr.Tab("Gestione Database"):
        gr.Markdown("## Operazioni sui Database")
        
        with gr.Row():
            with gr.Column():
                gr.Markdown("### Crea Database")
                db_name_input = gr.Textbox(label="Nome Nuovo Database")
                create_db_button = gr.Button("Crea Database")
                create_output = gr.Textbox(label="Stato Creazione")
            
            with gr.Column():
                gr.Markdown("### Rinomina Database")
                modify_db_old_name = gr.Dropdown(choices=databases, label="Database da Rinominare")
                modify_db_new_name = gr.Textbox(label="Nuovo Nome")
                modify_db_button = gr.Button("Rinomina Database")
                modify_output = gr.Textbox(label="Stato Modifica")
            
            with gr.Column():
                gr.Markdown("### Elimina Database") 
                delete_db_dropdown = gr.Dropdown(choices=databases, label="Database da Eliminare")
                delete_db_button = gr.Button("Elimina Database")
                delete_output = gr.Textbox(label="Stato Eliminazione")

        # Eventi per i pulsanti di gestione DB
        create_db_button.click(
            create_database,           # funzione
            inputs=db_name_input,      # input
            outputs=create_output      # output
        ).then(
            update_dropdowns,
            outputs=[db_name_upload, db_name_list, db_name_chat, db_name_new, modify_db_old_name, delete_db_dropdown]
        )

        modify_db_button.click(
            modify_database,
            inputs=[modify_db_old_name, modify_db_new_name],
            outputs=modify_output
        ).then(
            update_dropdowns,
            outputs=[db_name_upload, db_name_list, db_name_chat, db_name_new, modify_db_old_name, delete_db_dropdown]
        )

        delete_db_button.click(
            delete_database,
            inputs=delete_db_dropdown,
            outputs=delete_output
        ).then(
            update_dropdowns,
            outputs=[db_name_upload, db_name_list, db_name_chat, db_name_new, modify_db_old_name, delete_db_dropdown]
        )


    # =============================================
    #         TAB: Gestione Documenti
    # =============================================
    with gr.Tab("Gestione Documenti"):
        with gr.Column():
            gr.Markdown("### Carica Documenti")
            with gr.Row():
                file_input = gr.File(
                    label="Carica i tuoi documenti", 
                    file_types=[".txt", ".pdf", ".docx"], 
                    file_count="multiple"
                )
                db_name_upload = gr.Dropdown(
                    choices=databases, 
                    label="Seleziona Database", 
                    value="default_db"
                )
            
            with gr.Row():
                title_input = gr.Textbox(label="Titolo del documento")
                author_input = gr.Textbox(label="Autore")
            
            upload_button = gr.Button("Indicizza Documenti")
            upload_output = gr.Textbox(label="Stato Upload")
            
            with gr.Column():
                gr.Markdown("### Documenti nel Database")
                db_name_list = gr.Dropdown(
                    choices=databases, 
                    label="Seleziona Database", 
                    value="default_db"
                )
                list_button = gr.Button("Visualizza Files")
                list_output = gr.Textbox(label="Files nel Database")
                delete_file_input = gr.Textbox(label="Nome file da eliminare")
                delete_file_button = gr.Button("Elimina File")
                delete_file_output = gr.Textbox(label="Stato Eliminazione")

        # Eventi
        upload_button.click(
            upload_and_index,
            inputs=[file_input, title_input, author_input, db_name_upload],
            outputs=upload_output
        ).then(
            list_indexed_files,
            inputs=db_name_list,
            outputs=list_output
        )

        list_button.click(
            list_indexed_files,
            inputs=db_name_list,
            outputs=list_output
        )

        delete_file_button.click(
            delete_file_from_database,
            inputs=[delete_file_input, db_name_list],
            outputs=delete_file_output
        ).then(
            list_indexed_files,
            inputs=db_name_list,
            outputs=list_output
        ).then(
            update_dropdowns,
            outputs=[db_name_upload, db_name_list, db_name_chat, db_name_new, modify_db_old_name, delete_db_dropdown]
        )


    # =============================================
    #      TAB: Visualizza Documenti Indicizzati
    # =============================================
    with gr.Tab("Visualizza Documenti Indicizzati"):
        with gr.Column():
            gr.Markdown("### Documenti nel Database")
            db_name_list = gr.Dropdown(
                choices=databases, 
                label="Seleziona Database", 
                value="default_db",
                interactive=True
            )
            list_button = gr.Button("Visualizza Documenti")
            list_output = gr.Textbox(
                label="Elenco Documenti",
                lines=10,
                interactive=False,
                value="Clicca 'Visualizza Documenti' per vedere l'elenco"
            )

            list_button.click(
                fn=list_indexed_documents,
                inputs=[db_name_list],
                outputs=[list_output],
                api_name="list_docs"
            )

    # =============================================
    #         TAB: Nuove Funzionalità
    # =============================================
    with gr.Tab("Nuove Funzionalità"):
        gr.Markdown("## Cerca Documenti e Genera Riassunto")

        db_name_new = gr.Dropdown(choices=databases, label="Seleziona Database", value="default_db")
        search_input = gr.Textbox(label="Inserisci Termine di Ricerca")
        search_button = gr.Button("Cerca Documenti")
        search_output = gr.Textbox(label="Documenti Trovati")

        summary_button = gr.Button("Genera Riassunto")
        summary_output = gr.Textbox(label="Riassunto")

        search_button.click(
            search_documents,
            inputs=[search_input, db_name_new],
            outputs=search_output
        )
        # Esempio di eventuale generazione riassunto
        # summary_button.click(
        #     generate_summary,
        #     inputs=db_name_new,
        #     outputs=summary_output
        # )

# Avvio dell'app
if __name__ == "__main__":
    rag_chatbot.launch()