"""Gradio interface for the chat application."""

# AUTOGENERATED! DO NOT EDIT! File to edit: ../../nbs/02_ui.ipynb.

# %% auto 0
__all__ = ['GradioChat', 'create_chat_app']

# %% ../../nbs/02_ui.ipynb 3
import gradio as gr
import tempfile
import datetime
import os
from typing import List, Tuple, Dict, Generator
from fastcore.basics import patch
from .config import ChatAppConfig, ModelConfig
from .app import BaseChatApp
from pathlib import Path

# %% ../../nbs/02_ui.ipynb 6
class GradioChat:
    """Gradio interface for the chat application"""
    
    def __init__(self, app: BaseChatApp):
        """Initialize with a configured BaseChatApp"""
        self.app = app
        self.interface = None
    
    def respond(self, message: str, chat_history: List[Dict[str, str]]) -> Tuple[str, List[Tuple[str, str]]]:
        """Generate a response to the user message and update chat history"""
        # Store the current chat history in the app
        self.app.chat_history = chat_history
        
        # Generate response
        response = self.app.generate_response(message)
        
        # Update chat history
        chat_history.append({"role": "user", "content": message})
        chat_history.append({"role": "assistant", "content": response})
        
        # Return empty message (to clear input) and updated history
        return "", chat_history
    
    def respond_stream(self, message: str, chat_history: List[Tuple[str, str]]) -> Generator[Tuple[str, List[Tuple[str, str]]], None, None]:
        """Generate a streaming response to the user message"""
        # Store the current chat history in the app
        self.app.chat_history = chat_history
        
        # Add user message to history with empty assistant response
        chat_history.append({"role": "user", "content": message})
        
        # Stream the response
        accumulated_text = ""
        for text_chunk in self.app.generate_stream(message):
            accumulated_text += text_chunk
            
            # Update the last assistant message
            updated_history = chat_history.copy()
            updated_history.append({"role": "assistant", "content": accumulated_text})
            
            # Yield empty message and updated history
            yield "", updated_history

# %% ../../nbs/02_ui.ipynb 9
from datetime import datetime


@patch
def build_interface(self:GradioChat) -> gr.Blocks:
    """Build and return the Gradio interface"""
    with gr.Blocks(theme=self.app.config.theme, title=self.app.config.app_name) as interface:
        with gr.Row():
            # Left column for logo
            with gr.Column(scale=1):
                if self.app.config.logo_path:
                    gr.Image(value=self.app.config.logo_path,
                        show_label=False,
                        container=False,
                        show_download_button=False,
                        show_fullscreen_button=False,
                        height=80,
                        width=80)
                else:
                    gr.Image(value=None,
                        show_label=False,
                        container=False,
                        show_download_button=False,
                        show_fullscreen_button=False,
                        height=80,
                        width=80)
            with gr.Column(scale=4):
                # App title and description
                gr.Markdown(f"# {self.app.config.app_name}")
                if self.app.config.description:
                    gr.Markdown(self.app.config.description)
        
        # Chat interface
        chatbot = gr.Chatbot(
            height=500,
            label="Conversation",
            type="messages",
            editable=True,
            show_copy_button=True,
            show_copy_all_button=True)
        msg = gr.Textbox(
            placeholder="Type your message here...",
            label="Your message",
            lines=2
        )
        
        # Buttons
        with gr.Row():
            submit_btn = gr.Button("Send", variant="primary")
            clear_btn = gr.ClearButton([msg, chatbot], value="Clear chat")

        # Export functionality
        with gr.Accordion("Export Options", open=False):
            gr.Markdown("Select export options:")
            
            # Buttons for copying and downloading
            with gr.Row():
                download_btn = gr.DownloadButton(
                    label="Download as Markdown",
                    variant="secondary",
                    visible=True,
                    interactive=True
                )
        
        # System prompt and context viewer (collapsible)
        with gr.Accordion("View System Information", open=False):
            if self.app.config.show_system_prompt:
                gr.Markdown(f"### System Prompt\n{self.app.config.system_prompt}")
            
            if self.app.config.show_context and hasattr(self.app, 'context_text') and self.app.context_text:
                gr.Markdown(f"### Additional Context\n{self.app.context_text}")
        
        # Set up event handlers
        submit_btn.click(
            self.respond,
            inputs=[msg, chatbot],
            outputs=[msg, chatbot]
        )
        
        msg.submit(
            self.respond,
            inputs=[msg, chatbot],
            outputs=[msg, chatbot]
        )

            # Export event handlers
        def format_last_response(chat_history):
            if not chat_history:
                return "No conversation to export."
            msg = chat_history[-1]

            return f"# Response\n\n{msg['content']}"
        
        def format_full_conversation(chat_history):
            if not chat_history:
                return "No conversation to export."
            
            md_str = f"# {self.app.config.app_name} - Conversation\n\n"
            
            for msg in chat_history:
                role = msg["role"]
                content = msg["content"]
                if role == "user":
                    md_str += f"**👤 User:**\n{content}\n\n"
                elif role == "assistant":
                    md_str += f"**🤖 Assistant+**\n{content}\n\n"
                else:
                    md_str += f"**{role}:**\n{content}\n\n"
            return md_str
            
        # File download functionality
        def download_chat(chat_history):
            md_content = format_full_conversation(chat_history)
            temp_dir = tempfile.gettempdir()
            filename = f"conversation_{datetime.today().strftime('%Y-%m-%d')}.md"
            filepath = Path(temp_dir) / filename
            
            with open(filepath, 'w', encoding='utf-8') as f:
                f.write(md_content)
            
            os.chmod(filepath, 0o644)

            return filepath

        download_btn.click(
            fn=download_chat,
            inputs=[chatbot],
            outputs=[download_btn]
        )
            
        # Initialize with starter prompt if available
        if self.app.config.starter_prompt:
            chatbot.value = [{"role": "assistant", "content": self.app.config.starter_prompt}]
        
        self.interface = interface
        return interface

# %% ../../nbs/02_ui.ipynb 11
@patch
def launch(self:GradioChat, **kwargs):
    """Launch the Gradio interface"""
    if self.interface is None:
        self.build_interface()
    
    return self.interface.launch(**kwargs)

# %% ../../nbs/02_ui.ipynb 14
def create_chat_app(
        config: ChatAppConfig # Instance from the config.ChatAppConfig module
        ) -> GradioChat:
    """Create a complete chat application from a configuration"""
    base_app = BaseChatApp(config)
    return GradioChat(base_app)
