"""
Chat screen for the MiniMax TUI interface.

Provides an interactive chat interface with conversation history, context file management,
and real-time AI response streaming. Enhanced with advanced Textual widgets for better UX.
"""

import os
import asyncio
from typing import List, Dict, Any, Optional
from pathlib import Path
from datetime import datetime

try:
    from textual.app import ComposeResult
    from textual.screen import Screen
    from textual.widgets import (
        Header, Footer, Input, TextLog, Tree, Static, 
        Button, Horizontal, Vertical, TabbedContent, 
        TabPane, ProgressBar, Label, DataTable, 
        LogViewer, OptionList, Switch, Select
    )
    from textual.containers import Container, ScrollableContainer
    from textual.reactive import reactive
    from textual.message import Message
    from textual.worker import Worker, get_current_worker
    from textual.binding import Binding
    from textual import work, events
    from textual.notifications import Notification
    from textual.coordinate import Coordinate
    from rich.markdown import Markdown
    from rich.syntax import Syntax
    from rich.panel import Panel
    from rich.text import Text
    from rich.console import Console
    TEXTUAL_AVAILABLE = True
except ImportError:
    TEXTUAL_AVAILABLE = False
    # Fallback classes for when Textual is not available
    class Screen:
        pass
    class ComposeResult:
        pass
    class Message:
        def __init__(self, *args, **kwargs):
            pass
    
    class Binding:
        def __init__(self, *args, **kwargs):
            pass
    
    class Input:
        def __init__(self, *args, **kwargs):
            pass
        class Submitted:
            def __init__(self, *args, **kwargs):
                self.value = ""
    
    # Add all missing widget fallback classes
    class Button:
        def __init__(self, *args, **kwargs):
            pass
        class Pressed:
            def __init__(self, *args, **kwargs):
                self.button = None
    
    class RadioButton:
        def __init__(self, *args, **kwargs):
            pass
        class Changed:
            def __init__(self, *args, **kwargs):
                self.radio_button = None
    
    class Switch:
        def __init__(self, *args, **kwargs):
            pass
        class Changed:
            def __init__(self, *args, **kwargs):
                self.switch = None
    
    class DataTable:
        def __init__(self, *args, **kwargs):
            pass
        class RowSelected:
            def __init__(self, *args, **kwargs):
                self.data_table = None
                self.row_key = None
    
    class LogViewer:
        def __init__(self, *args, **kwargs):
            pass
    
    class TabbedContent:
        def __init__(self, *args, **kwargs):
            pass
    
    class TabPane:
        def __init__(self, *args, **kwargs):
            pass
    
    class ProgressBar:
        def __init__(self, *args, **kwargs):
            pass
    
    class Label:
        def __init__(self, *args, **kwargs):
            pass
    
    class Static:
        def __init__(self, *args, **kwargs):
            pass
    
    class Container:
        def __init__(self, *args, **kwargs):
            pass
    
    class Horizontal:
        def __init__(self, *args, **kwargs):
            pass
    
    class Vertical:
        def __init__(self, *args, **kwargs):
            pass
    
    class ScrollableContainer:
        def __init__(self, *args, **kwargs):
            pass
    
    class Tree:
        def __init__(self, *args, **kwargs):
            pass
    
    class OptionList:
        def __init__(self, *args, **kwargs):
            pass
    
    class Select:
        def __init__(self, *args, **kwargs):
            pass
        class Changed:
            def __init__(self, *args, **kwargs):
                self.select = None
    
    class Header:
        def __init__(self, *args, **kwargs):
            pass
    
    class Footer:
        def __init__(self, *args, **kwargs):
            pass
    
    class TextLog:
        def __init__(self, *args, **kwargs):
            pass
    
    # Add reactive as a function
    def reactive(default, **kwargs):
        return default
    
    # Add events module fallback
    class events:
        class Key:
            def __init__(self, *args, **kwargs):
                self.key = ""
    
    # Add work decorator fallback
    def work(*args, **kwargs):
        def decorator(func):
            return func
        return decorator
    
    # Add Worker class fallback
    class Worker:
        def __init__(self, *args, **kwargs):
            pass
        def cancel(self):
            pass
        @property
        def is_finished(self):
            return True
    
    def get_current_worker():
        return None

# Import theme system
try:
    from ...ui.theme import (
        get_theme_config, get_color, get_icon, get_style,
        get_file_icon, get_css_variables
    )
    THEME_AVAILABLE = True
except ImportError:
    THEME_AVAILABLE = False
    # Fallback functions
    def get_theme_config(): return None
    def get_color(name, opacity=None): return "#ffffff"
    def get_icon(name): return "•"
    def get_style(name): return "default"
    def get_file_icon(filename): return "📄"
    def get_css_variables(): return {}


class ChatMessage(Message):
    """Message for chat events."""
    
    def __init__(self, content: str, is_user: bool = True) -> None:
        self.content = content
        self.is_user = is_user
        super().__init__()


class ContextFileAdded(Message):
    """Message for when a context file is added."""
    
    def __init__(self, file_path: str) -> None:
        self.file_path = file_path
        super().__init__()


class ContextFileRemoved(Message):
    """Message for when a context file is removed."""
    
    def __init__(self, file_path: str) -> None:
        self.file_path = file_path
        super().__init__()


class ChatScreen(Screen):
    """Interactive chat screen for MiniMax TUI with advanced widgets."""
    
    BINDINGS = [
        Binding("ctrl+c", "quit", "Quit"),
        Binding("ctrl+n", "new_chat", "New Chat"),
        Binding("ctrl+o", "add_file", "Add File"),
        Binding("ctrl+r", "remove_file", "Remove File"),
        Binding("ctrl+l", "clear_context", "Clear Context"),
        Binding("ctrl+f", "search_conversation", "Search"),
        Binding("ctrl+s", "save_conversation", "Save"),
        Binding("ctrl+t", "toggle_theme", "Toggle Theme"),
        Binding("f1", "show_help", "Help"),
        Binding("f2", "toggle_view_mode", "Toggle View"),
        Binding("escape", "focus_input", "Focus Input"),
        Binding("tab", "next_tab", "Next Tab"),
        Binding("shift+tab", "previous_tab", "Previous Tab"),
    ]
    
    # Remove embedded CSS - will be loaded from external theme.css
    CSS_PATH = None  # Will be set dynamically based on theme
    
    def __init__(self, client=None, config=None, **kwargs):
        super().__init__(**kwargs)
        self.client = client
        self.config = config
        self.context_files: List[Dict[str, Any]] = []
        self.conversation_history: List[Dict[str, str]] = []
        self.current_worker: Optional[Worker] = None
        self.is_processing = reactive(False)
        self.view_mode = reactive("table")  # "table" or "tree" for context view
        self.search_query = reactive("")
        self.auto_scroll = reactive(True)
        self.theme_config = get_theme_config() if THEME_AVAILABLE else None
        
        # Enhanced state management
        self.conversation_filter = "all"  # "all", "user", "assistant", "system", "error"
        self.streaming_response = ""
        self.response_buffer = []
        
    def compose(self) -> ComposeResult:
        """Compose the enhanced chat screen layout with tabbed interface."""
        # Main tabbed content container
        with TabbedContent(id="main_tabs"):
            # Chat Tab
            with TabPane("💬 Chat", id="chat_tab"):
                with Container(id="chat_container", classes="animate-fade-in"):
                    # Enhanced conversation log with LogViewer
                    yield LogViewer(
                        id="conversation_log",
                        highlight=True,
                        markup=True,
                        wrap=True,
                        auto_scroll=self.auto_scroll,
                        show_time=True
                    )
                    
                    # Enhanced progress container with animations
                    with Container(id="progress_container", classes="animate-slide-in-up"):
                        yield ProgressBar(
                            id="progress_bar",
                            show_eta=True,
                            show_percentage=True,
                            classes="animate-pulse"
                        )
                        yield Label("", id="progress_label", classes="text-muted")
                        yield Label("", id="streaming_indicator", classes="text-accent")
                    
                    # Enhanced input container with better controls
                    with Horizontal(id="input_container", classes="p-2"):
                        yield Input(
                            placeholder="Type your message here... (Enter to send, Shift+Enter for new line)",
                            id="message_input",
                            classes="flex-1"
                        )
                        yield Button(
                            f"{get_icon('processing')} Send", 
                            id="send_button", 
                            variant="primary",
                            classes="min-w-12"
                        )
                        yield Button(
                            f"{get_icon('close')} Stop", 
                            id="stop_button", 
                            variant="error",
                            classes="min-w-12 hidden"
                        )
            
            # Context Tab with enhanced file management
            with TabPane("📋 Context", id="context_tab"):
                with Container(id="context_container", classes="animate-fade-in"):
                    # Context controls
                    with Horizontal(id="context_controls", classes="p-2 bg-surface"):
                        yield Button(
                            f"{get_icon('file')} Add File", 
                            id="add_file_btn", 
                            variant="primary"
                        )
                        yield Button(
                            f"{get_icon('close')} Clear All", 
                            id="clear_context_btn", 
                            variant="warning"
                        )
                        yield Switch(
                            value=self.view_mode == "table",
                            id="view_mode_switch"
                        )
                        yield Label("Table View", classes="text-muted")
                    
                    # Dynamic context view (table or tree)
                    with Container(id="context_view_container"):
                        # DataTable for enhanced file metadata display
                        yield DataTable(
                            id="context_table",
                            show_header=True,
                            show_row_labels=False,
                            zebra_stripes=True,
                            cursor_type="row",
                            classes="border border-accent"
                        )
                        
                        # Tree view as alternative (initially hidden)
                        yield Tree(
                            "Context Files", 
                            id="context_tree",
                            classes="border border-accent hidden"
                        )
                    
                    # Enhanced context statistics
                    with Container(id="context_stats", classes="bg-surface-dark p-3 m-2"):
                        yield Static("", id="stats_content")
            
            # Settings Tab for configuration
            with TabPane("⚙️ Settings", id="settings_tab"):
                with Container(id="settings_container", classes="animate-fade-in p-4"):
                    with Vertical(classes="space-y-4"):
                        # Chat settings
                        yield Static("💬 Chat Settings", classes="text-primary text-bold")
                        
                        with Horizontal(classes="align-center"):
                            yield Label("Auto-scroll:", classes="w-32")
                            yield Switch(value=self.auto_scroll, id="auto_scroll_switch")
                        
                        with Horizontal(classes="align-center"):
                            yield Label("Message Filter:", classes="w-32")
                            yield Select(
                                options=[
                                    ("all", "All Messages"),
                                    ("user", "User Only"),
                                    ("assistant", "Assistant Only"),
                                    ("system", "System Only"),
                                    ("error", "Errors Only")
                                ],
                                value="all",
                                id="message_filter_select"
                            )
                        
                        # Theme settings
                        yield Static("🎨 Appearance", classes="text-primary text-bold")
                        
                        with Horizontal(classes="align-center"):
                            yield Label("Theme:", classes="w-32")
                            yield Select(
                                options=[
                                    ("dark", "Dark Theme"),
                                    ("light", "Light Theme"),
                                    ("auto", "Auto Detect")
                                ],
                                value="dark",
                                id="theme_select"
                            )
                        
                        # Performance settings
                        yield Static("⚡ Performance", classes="text-primary text-bold")
                        
                        with Horizontal(classes="align-center"):
                            yield Label("Max History:", classes="w-32")
                            yield Select(
                                options=[
                                    ("50", "50 messages"),
                                    ("100", "100 messages"),
                                    ("200", "200 messages"),
                                    ("500", "500 messages")
                                ],
                                value="100",
                                id="max_history_select"
                            )
    
    def on_mount(self) -> None:
        """Initialize the enhanced screen when mounted."""
        # Apply theme-based styling
        self._apply_theme_styling()
        
        # Initialize context table columns
        self._setup_context_table()
        
        # Focus input and show welcome messages
        self.query_one("#message_input").focus()
        self._update_context_stats()
        
        # Enhanced welcome messages with icons
        welcome_icon = get_icon('chat')
        self._add_system_message(f"{welcome_icon} MiniMax Chat Interface Ready")
        self._add_system_message("Enhanced with advanced widgets and better UX")
        self._add_system_message("Use tabs to navigate: Chat, Context, Settings")
        self._add_system_message("Type your message and press Enter or click Send")
        
        # Show notification for successful initialization
        if hasattr(self.app, 'notify'):
            self.app.notify(
                "Chat interface initialized successfully",
                title="Welcome",
                severity="information",
                timeout=3.0
            )
    
    def _apply_theme_styling(self) -> None:
        """Apply theme-based styling to the screen."""
        if not THEME_AVAILABLE:
            return
        
        try:
            # Get CSS variables from theme
            css_vars = get_css_variables()
            
            # Apply dynamic styling based on theme
            # This would be expanded with actual CSS application logic
            pass
        except Exception as e:
            # Fallback to default styling
            pass
    
    def _setup_context_table(self) -> None:
        """Setup the context files DataTable with proper columns."""
        table = self.query_one("#context_table", DataTable)
        
        # Add columns with proper styling
        table.add_column("File", key="file", width=30)
        table.add_column("Type", key="type", width=12)
        table.add_column("Size", key="size", width=10)
        table.add_column("Lines", key="lines", width=8)
        table.add_column("Modified", key="modified", width=20)
        table.add_column("Language", key="language", width=12)
        
        # Configure table properties
        table.cursor_type = "row"
        table.zebra_stripes = True
    
    def on_input_submitted(self, event: Input.Submitted) -> None:
        """Handle input submission with enhanced features."""
        if event.input.id == "message_input":
            # Check for Shift+Enter (new line) vs Enter (send)
            self._send_message()
    
    def on_button_pressed(self, event: Button.Pressed) -> None:
        """Handle button presses with enhanced functionality."""
        button_id = event.button.id
        
        if button_id == "send_button":
            self._send_message()
        elif button_id == "stop_button":
            self._stop_processing()
        elif button_id == "add_file_btn":
            self._show_file_picker()
        elif button_id == "clear_context_btn":
            self._confirm_clear_context()
    
    def on_switch_changed(self, event: Switch.Changed) -> None:
        """Handle switch changes for settings."""
        switch_id = event.switch.id
        
        if switch_id == "view_mode_switch":
            self.view_mode = "table" if event.value else "tree"
            self._toggle_context_view()
        elif switch_id == "auto_scroll_switch":
            self.auto_scroll = event.value
            self._update_auto_scroll()
    
    def on_select_changed(self, event: Select.Changed) -> None:
        """Handle select dropdown changes."""
        select_id = event.select.id
        
        if select_id == "message_filter_select":
            self.conversation_filter = event.value
            self._apply_message_filter()
        elif select_id == "theme_select":
            self._change_theme(event.value)
        elif select_id == "max_history_select":
            self._update_max_history(int(event.value))
    
    def on_data_table_row_selected(self, event: DataTable.RowSelected) -> None:
        """Handle context table row selection."""
        if event.data_table.id == "context_table":
            self._show_file_context_menu(event.row_key)
    
    def on_key(self, event: events.Key) -> None:
        """Handle enhanced keyboard navigation."""
        if event.key == "ctrl+f":
            self._show_search_dialog()
        elif event.key == "ctrl+s":
            self._save_conversation()
        elif event.key == "f2":
            self._toggle_view_mode()
        elif event.key == "delete" and self._is_context_focused():
            self._delete_selected_context_file()
    
    def _send_message(self) -> None:
        """Send a user message."""
        message_input = self.query_one("#message_input", Input)
        message = message_input.value.strip()
        
        if not message:
            return
        
        # Clear input
        message_input.value = ""
        
        # Handle special commands
        if message.lower() in ['exit', 'quit', 'bye']:
            self.app.exit()
            return
        elif message.lower() == 'help':
            self._show_help()
            return
        elif message.lower() == 'context':
            self._show_context_info()
            return
        elif message.lower() == 'clear':
            self._clear_conversation()
            return
        elif message.startswith('add '):
            file_path = message[4:].strip()
            self._add_file_to_context(file_path)
            return
        elif message.startswith('remove '):
            file_path = message[7:].strip()
            self._remove_file_from_context(file_path)
            return
        
        # Add user message to conversation
        self._add_user_message(message)
        
        # Process with AI
        self._process_ai_message(message)
    
    def _add_user_message(self, message: str) -> None:
        """Add a user message to the enhanced conversation log."""
        log_viewer = self.query_one("#conversation_log", LogViewer)
        
        # Create enhanced user message with timestamp and styling
        timestamp = datetime.now().strftime("%H:%M:%S")
        user_icon = get_icon('chat')
        
        # Use theme colors
        primary_color = get_color('primary')
        
        user_panel = Panel(
            message,
            title=f"{user_icon} You [{timestamp}]",
            title_align="left",
            border_style=primary_color,
            padding=(0, 1),
            classes="user-message animate-slide-in-left"
        )
        
        log_viewer.write(user_panel, level="INFO")
        self._scroll_to_bottom()
    
    def _add_assistant_message(self, message: str, streaming: bool = False) -> None:
        """Add an assistant message with enhanced formatting and streaming support."""
        log_viewer = self.query_one("#conversation_log", LogViewer)
        
        timestamp = datetime.now().strftime("%H:%M:%S")
        assistant_icon = get_icon('processing') if streaming else get_icon('success')
        accent_color = get_color('accent')
        
        # Enhanced markdown parsing with better error handling
        try:
            markdown_content = Markdown(message, code_theme="monokai")
            assistant_panel = Panel(
                markdown_content,
                title=f"{assistant_icon} MiniMax [{timestamp}]",
                title_align="left",
                border_style=accent_color,
                padding=(0, 1),
                classes="assistant-message animate-slide-in-right"
            )
        except Exception as e:
            # Enhanced fallback with syntax highlighting for code blocks
            if "```" in message:
                # Try to extract and highlight code blocks
                formatted_message = self._format_code_blocks(message)
            else:
                formatted_message = message
            
            assistant_panel = Panel(
                formatted_message,
                title=f"{assistant_icon} MiniMax [{timestamp}]",
                title_align="left",
                border_style=accent_color,
                padding=(0, 1),
                classes="assistant-message animate-slide-in-right"
            )
        
        log_viewer.write(assistant_panel, level="INFO")
        self._scroll_to_bottom()
    
    def _add_system_message(self, message: str) -> None:
        """Add an enhanced system message."""
        log_viewer = self.query_one("#conversation_log", LogViewer)
        
        timestamp = datetime.now().strftime("%H:%M:%S")
        info_icon = get_icon('info')
        info_color = get_color('info')
        
        system_text = Text()
        system_text.append(f"{info_icon} ", style=info_color)
        system_text.append(f"[{timestamp}] ", style="dim")
        system_text.append(message, style=f"dim {info_color}")
        
        log_viewer.write(system_text, level="DEBUG")
    
    def _add_error_message(self, message: str) -> None:
        """Add an enhanced error message with notification."""
        log_viewer = self.query_one("#conversation_log", LogViewer)
        
        timestamp = datetime.now().strftime("%H:%M:%S")
        error_icon = get_icon('error')
        error_color = get_color('error')
        
        error_panel = Panel(
            message,
            title=f"{error_icon} Error [{timestamp}]",
            title_align="left",
            border_style=error_color,
            padding=(0, 1),
            classes="error-message animate-bounce"
        )
        
        log_viewer.write(error_panel, level="ERROR")
        
        # Show notification for errors
        if hasattr(self.app, 'notify'):
            self.app.notify(
                message,
                title="Error",
                severity="error",
                timeout=5.0
            )
        
        self._scroll_to_bottom()
    
    def _format_code_blocks(self, message: str) -> str:
        """Format code blocks in messages with syntax highlighting."""
        # Simple code block detection and formatting
        import re
        
        # Pattern to match code blocks
        code_pattern = r'```(\w+)?\n(.*?)\n```'
        
        def replace_code_block(match):
            language = match.group(1) or 'text'
            code = match.group(2)
            
            try:
                syntax = Syntax(code, language, theme="monokai", line_numbers=False)
                return str(syntax)
            except:
                return f"[code]{code}[/code]"
        
        return re.sub(code_pattern, replace_code_block, message, flags=re.DOTALL)
    
    def _scroll_to_bottom(self) -> None:
        """Scroll conversation log to bottom if auto-scroll is enabled."""
        if self.auto_scroll:
            try:
                log_viewer = self.query_one("#conversation_log", LogViewer)
                log_viewer.scroll_end()
            except:
                pass
    
    @work(exclusive=True)
    async def _process_ai_message(self, message: str) -> None:
        """Process a message with AI in a worker thread."""
        try:
            self.is_processing = True
            self._show_progress("Processing your message...")
            
            # Build context for AI
            context_parts = []
            
            # Add file contexts
            if self.context_files:
                context_parts.append("=== CONTEXT FILES ===")
                for file_info in self.context_files:
                    context_parts.append(f"File: {file_info['path']}")
                    context_parts.append(f"Language: {file_info['language']}")
                    context_parts.append("Content:")
                    context_parts.append(file_info['content'])
                    context_parts.append("=" * 30)
            
            # Add conversation history (last 5 exchanges)
            if self.conversation_history:
                context_parts.append("=== RECENT CONVERSATION ===")
                for exchange in self.conversation_history[-5:]:
                    context_parts.append(f"User: {exchange['user']}")
                    context_parts.append(f"Assistant: {exchange['assistant']}")
                    context_parts.append("-" * 20)
            
            # Combine context
            full_context = "\n".join(context_parts) if context_parts else None
            
            # Create the prompt
            prompt = f"""
You are a helpful coding assistant. Please help with the following request:

{message}

Please provide clear, practical advice and code examples when appropriate.
If the request involves code modification, provide specific suggestions.
"""
            
            # Simulate AI response (replace with actual AI client call)
            await asyncio.sleep(0.5)  # Simulate processing time
            
            # For now, create a mock response
            response = await self._get_ai_response(prompt, full_context)
            
            if response:
                # Add to conversation history
                self.conversation_history.append({
                    'user': message,
                    'assistant': response
                })
                
                # Keep only last 10 exchanges
                if len(self.conversation_history) > 10:
                    self.conversation_history = self.conversation_history[-10:]
                
                # Add assistant response to UI
                self.call_from_thread(self._add_assistant_message, response)
            else:
                self.call_from_thread(self._add_error_message, "Failed to get AI response")
                
        except Exception as e:
            self.call_from_thread(self._add_error_message, f"Error processing message: {str(e)}")
        finally:
            self.is_processing = False
            self.call_from_thread(self._hide_progress)
    
    async def _get_ai_response(self, prompt: str, context: Optional[str] = None) -> str:
        """Get AI response (placeholder for actual implementation)."""
        # This would be replaced with actual AI client integration
        # For now, return a mock response
        await asyncio.sleep(1)  # Simulate API call
        
        return f"""I understand you're asking about: "{prompt[:50]}..."

This is a placeholder response. In the actual implementation, this would:
1. Use the MiniMax AI client to process your request
2. Include the provided context files in the analysis
3. Stream the response in real-time
4. Handle errors gracefully

Context files available: {len(self.context_files)}
Conversation history: {len(self.conversation_history)} exchanges"""
    
    def _show_progress(self, message: str, total: Optional[int] = None) -> None:
        """Show enhanced progress indicator with animations."""
        progress_bar = self.query_one("#progress_bar", ProgressBar)
        progress_label = self.query_one("#progress_label", Label)
        streaming_indicator = self.query_one("#streaming_indicator", Label)
        
        progress_bar.remove_class("hidden")
        progress_bar.add_class("animate-pulse")
        progress_label.update(message)
        
        if total:
            progress_bar.total = total
        else:
            # Indeterminate progress
            progress_bar.advance(0)
        
        # Show streaming indicator for AI responses
        if "processing" in message.lower() or "generating" in message.lower():
            streaming_indicator.update("🔄 Streaming response...")
            streaming_indicator.add_class("animate-spin")
    
    def _hide_progress(self) -> None:
        """Hide enhanced progress indicator."""
        progress_bar = self.query_one("#progress_bar", ProgressBar)
        progress_label = self.query_one("#progress_label", Label)
        streaming_indicator = self.query_one("#streaming_indicator", Label)
        
        progress_bar.add_class("hidden")
        progress_bar.remove_class("animate-pulse")
        progress_label.update("")
        streaming_indicator.update("")
        streaming_indicator.remove_class("animate-spin")
    
    def _stop_processing(self) -> None:
        """Stop current AI processing."""
        if self.current_worker and not self.current_worker.is_finished:
            self.current_worker.cancel()
            self._hide_progress()
            self.is_processing = False
            
            # Show stop button, hide send button
            send_btn = self.query_one("#send_button", Button)
            stop_btn = self.query_one("#stop_button", Button)
            send_btn.remove_class("hidden")
            stop_btn.add_class("hidden")
            
            self._add_system_message("⏹️ Processing stopped by user")
            
            if hasattr(self.app, 'notify'):
                self.app.notify(
                    "Processing stopped",
                    severity="warning",
                    timeout=2.0
                )
    
    def _update_auto_scroll(self) -> None:
        """Update auto-scroll setting for conversation log."""
        try:
            log_viewer = self.query_one("#conversation_log", LogViewer)
            log_viewer.auto_scroll = self.auto_scroll
        except:
            pass
    
    def _apply_message_filter(self) -> None:
        """Apply message filter to conversation log."""
        # This would filter messages in the LogViewer based on the selected filter
        # Implementation depends on LogViewer capabilities
        if hasattr(self.app, 'notify'):
            filter_name = self.conversation_filter.title()
            self.app.notify(
                f"Filter applied: {filter_name}",
                severity="information",
                timeout=2.0
            )
    
    def _change_theme(self, theme_name: str) -> None:
        """Change the application theme."""
        if THEME_AVAILABLE:
            try:
                from ...ui.theme import set_theme
                set_theme(theme_name)
                self._apply_theme_styling()
                
                if hasattr(self.app, 'notify'):
                    self.app.notify(
                        f"Theme changed to {theme_name.title()}",
                        severity="information",
                        timeout=2.0
                    )
            except Exception as e:
                self._add_error_message(f"Failed to change theme: {e}")
    
    def _update_max_history(self, max_count: int) -> None:
        """Update maximum conversation history count."""
        if len(self.conversation_history) > max_count:
            self.conversation_history = self.conversation_history[-max_count:]
            
        if hasattr(self.app, 'notify'):
            self.app.notify(
                f"Max history set to {max_count}",
                severity="information",
                timeout=2.0
            )
    
    def _add_file_to_context(self, file_path: str) -> None:
        """Add a file to the conversation context with enhanced feedback."""
        if not os.path.exists(file_path):
            self._add_error_message(f"File not found: {file_path}")
            return
        
        # Check if already in context
        for file_info in self.context_files:
            if file_info['path'] == file_path:
                self._add_system_message(f"File already in context: {file_path}")
                if hasattr(self.app, 'notify'):
                    self.app.notify(
                        f"File already in context",
                        title="Duplicate File",
                        severity="warning",
                        timeout=3.0
                    )
                return
        
        try:
            # Show progress for large files
            file_size = os.path.getsize(file_path)
            if file_size > 100000:  # 100KB
                self._show_progress(f"Reading large file: {Path(file_path).name}")
            
            # Read file content with encoding detection
            content = self._read_file_with_encoding(file_path)
            
            # Detect language from file extension
            language = self._detect_language(file_path)
            
            # Enhanced file info with metadata
            file_info = {
                'path': file_path,
                'language': language,
                'content': content,
                'size': len(content),
                'added_at': datetime.now().isoformat(),
                'encoding': 'utf-8',  # Could be detected
                'lines': content.count('\n') + 1
            }
            
            self.context_files.append(file_info)
            
            # Enhanced success message
            file_icon = get_file_icon(file_path)
            success_msg = f"{file_icon} Added to context: {Path(file_path).name}"
            self._add_system_message(success_msg)
            
            # Update views
            self._update_context_view()
            self._update_context_stats()
            
            # Show success notification
            if hasattr(self.app, 'notify'):
                self.app.notify(
                    f"Added {Path(file_path).name} ({self._format_size(file_info['size'])})",
                    title="File Added",
                    severity="information",
                    timeout=3.0
                )
            
            if file_size > 100000:
                self._hide_progress()
            
        except Exception as e:
            self._add_error_message(f"Error reading file {file_path}: {str(e)}")
            if file_size > 100000:
                self._hide_progress()
    
    def _read_file_with_encoding(self, file_path: str) -> str:
        """Read file with automatic encoding detection."""
        encodings = ['utf-8', 'utf-16', 'latin-1', 'cp1252']
        
        for encoding in encodings:
            try:
                with open(file_path, 'r', encoding=encoding) as f:
                    return f.read()
            except UnicodeDecodeError:
                continue
        
        # If all encodings fail, read as binary and decode with errors='replace'
        with open(file_path, 'rb') as f:
            return f.read().decode('utf-8', errors='replace')
    
    def _remove_file_from_context(self, file_path: str) -> None:
        """Remove a file from the conversation context."""
        for i, file_info in enumerate(self.context_files):
            if file_info['path'] == file_path:
                del self.context_files[i]
                self._add_system_message(f"Removed from context: {file_path}")
                self._update_context_tree()
                self._update_context_stats()
                return
        
        self._add_system_message(f"File not in context: {file_path}")
    
    def _clear_context(self) -> None:
        """Clear all context files."""
        self.context_files.clear()
        self._add_system_message("Context files cleared")
        self._update_context_tree()
        self._update_context_stats()
    
    def _clear_conversation(self) -> None:
        """Clear conversation history."""
        conversation_log = self.query_one("#conversation_log", TextLog)
        conversation_log.clear()
        self.conversation_history.clear()
        self._add_system_message("🤖 MiniMax Chat Interface Ready")
        self._add_system_message("Conversation cleared. How can I help you?")
    
    def _update_context_view(self) -> None:
        """Update both context table and tree views."""
        if self.view_mode == "table":
            self._update_context_table()
        else:
            self._update_context_tree()
    
    def _update_context_table(self) -> None:
        """Update the enhanced context files DataTable."""
        table = self.query_one("#context_table", DataTable)
        table.clear()
        
        if not self.context_files:
            # Add empty state row
            table.add_row(
                "No files in context",
                "-", "-", "-", "-", "-",
                key="empty"
            )
            return
        
        # Add file data with enhanced metadata
        for i, file_info in enumerate(self.context_files):
            path = Path(file_info['path'])
            file_icon = get_file_icon(path.name)
            
            # Calculate additional metadata
            line_count = file_info['content'].count('\n') + 1
            modified_time = self._get_file_modified_time(file_info['path'])
            
            table.add_row(
                f"{file_icon} {path.name}",
                file_info['language'].title(),
                self._format_size(file_info['size']),
                str(line_count),
                modified_time,
                file_info['language'],
                key=f"file_{i}"
            )
    
    def _update_context_tree(self) -> None:
        """Update the enhanced context files tree."""
        tree = self.query_one("#context_tree", Tree)
        tree.clear()
        
        if not self.context_files:
            empty_icon = get_icon('info')
            tree.root.add_leaf(f"{empty_icon} No files in context")
            return
        
        # Enhanced tree with icons and metadata
        dirs = {}
        for file_info in self.context_files:
            path = Path(file_info['path'])
            dir_name = str(path.parent) if path.parent != Path('.') else "Current Directory"
            
            if dir_name not in dirs:
                dirs[dir_name] = []
            dirs[dir_name].append(file_info)
        
        # Add to tree with enhanced formatting
        folder_icon = get_icon('folder')
        for dir_name, files in dirs.items():
            if len(dirs) > 1:
                dir_node = tree.root.add(f"{folder_icon} {dir_name}")
                for file_info in files:
                    file_icon = get_file_icon(file_info['path'])
                    file_name = Path(file_info['path']).name
                    size_str = self._format_size(file_info['size'])
                    file_label = f"{file_icon} {file_name} ({file_info['language']}, {size_str})"
                    dir_node.add_leaf(file_label)
                dir_node.expand()
            else:
                # If only one directory, don't show directory level
                for file_info in files:
                    file_icon = get_file_icon(file_info['path'])
                    file_name = Path(file_info['path']).name
                    size_str = self._format_size(file_info['size'])
                    file_label = f"{file_icon} {file_name} ({file_info['language']}, {size_str})"
                    tree.root.add_leaf(file_label)
    
    def _get_file_modified_time(self, file_path: str) -> str:
        """Get formatted file modification time."""
        try:
            mtime = os.path.getmtime(file_path)
            return datetime.fromtimestamp(mtime).strftime("%Y-%m-%d %H:%M")
        except:
            return "Unknown"
    
    def _toggle_context_view(self) -> None:
        """Toggle between table and tree view for context files."""
        table = self.query_one("#context_table", DataTable)
        tree = self.query_one("#context_tree", Tree)
        
        if self.view_mode == "table":
            table.remove_class("hidden")
            tree.add_class("hidden")
            self._update_context_table()
        else:
            table.add_class("hidden")
            tree.remove_class("hidden")
            self._update_context_tree()
        
        # Show notification about view change
        if hasattr(self.app, 'notify'):
            view_name = "Table" if self.view_mode == "table" else "Tree"
            self.app.notify(
                f"Switched to {view_name} view",
                severity="information",
                timeout=2.0
            )
    
    def _update_context_stats(self) -> None:
        """Update enhanced context statistics with more details."""
        stats_content = self.query_one("#stats_content", Static)
        
        file_count = len(self.context_files)
        total_size = sum(file_info['size'] for file_info in self.context_files)
        history_count = len(self.conversation_history)
        
        # Calculate additional statistics
        total_lines = sum(file_info['content'].count('\n') + 1 for file_info in self.context_files)
        languages = set(file_info['language'] for file_info in self.context_files)
        
        # Enhanced statistics with icons
        stats_icon = get_icon('info')
        files_icon = get_icon('file')
        size_icon = get_icon('file_data')
        history_icon = get_icon('chat')
        
        stats_text = f"""{stats_icon} Context Statistics:

{files_icon} Files: {file_count}
{size_icon} Total size: {self._format_size(total_size)}
📝 Total lines: {total_lines:,}
🔤 Languages: {len(languages)}
{history_icon} History: {history_count} exchanges

💾 Memory usage: {self._estimate_memory_usage()}
🕒 Last updated: {datetime.now().strftime("%H:%M:%S")}"""
        
        if languages:
            lang_list = ", ".join(sorted(languages))
            stats_text += f"\n🌐 Used: {lang_list}"
        
        stats_content.update(stats_text)
    
    def _estimate_memory_usage(self) -> str:
        """Estimate memory usage of context and conversation."""
        context_size = sum(len(file_info['content']) for file_info in self.context_files)
        history_size = sum(len(exchange['user']) + len(exchange['assistant']) 
                          for exchange in self.conversation_history)
        total_chars = context_size + history_size
        
        # Rough estimation: 1 char ≈ 1 byte, plus overhead
        estimated_bytes = total_chars * 2  # Factor for overhead
        return self._format_size(estimated_bytes)
    
    def _detect_language(self, file_path: str) -> str:
        """Detect programming language from file extension."""
        ext = Path(file_path).suffix.lower()
        
        language_map = {
            '.py': 'python',
            '.js': 'javascript',
            '.ts': 'typescript',
            '.jsx': 'jsx',
            '.tsx': 'tsx',
            '.java': 'java',
            '.cpp': 'cpp',
            '.c': 'c',
            '.h': 'c',
            '.hpp': 'cpp',
            '.cs': 'csharp',
            '.php': 'php',
            '.rb': 'ruby',
            '.go': 'go',
            '.rs': 'rust',
            '.swift': 'swift',
            '.kt': 'kotlin',
            '.scala': 'scala',
            '.sh': 'bash',
            '.bash': 'bash',
            '.zsh': 'zsh',
            '.fish': 'fish',
            '.ps1': 'powershell',
            '.html': 'html',
            '.css': 'css',
            '.scss': 'scss',
            '.sass': 'sass',
            '.less': 'less',
            '.xml': 'xml',
            '.json': 'json',
            '.yaml': 'yaml',
            '.yml': 'yaml',
            '.toml': 'toml',
            '.ini': 'ini',
            '.cfg': 'ini',
            '.conf': 'ini',
            '.md': 'markdown',
            '.txt': 'text',
            '.sql': 'sql',
            '.r': 'r',
            '.R': 'r',
            '.m': 'matlab',
            '.pl': 'perl',
            '.lua': 'lua',
            '.vim': 'vim',
            '.dockerfile': 'dockerfile',
        }
        
        return language_map.get(ext, 'text')
    
    def _format_size(self, size: int) -> str:
        """Format file size in human readable format."""
        for unit in ['B', 'KB', 'MB', 'GB']:
            if size < 1024:
                return f"{size:.1f} {unit}"
            size /= 1024
        return f"{size:.1f} TB"
    
    def _show_help(self) -> None:
        """Show help information."""
        help_text = """🔧 Chat Commands:
• help - Show this help
• context - Show context info
• clear - Clear conversation
• add <file> - Add file to context
• remove <file> - Remove file from context
• exit/quit/bye - Exit chat

⌨️ Keyboard Shortcuts:
• Ctrl+N - New chat
• Ctrl+O - Add file dialog
• Ctrl+R - Remove file dialog
• Ctrl+L - Clear context
• F1 - Show help
• Esc - Focus input
• Ctrl+C - Quit

💡 Tips:
• Ask questions about your code
• Request code reviews or explanations
• Get help with debugging
• Ask for code generation or modifications
• Context files help the AI understand your project"""
        
        self._add_system_message("Help Information:")
        conversation_log = self.query_one("#conversation_log", TextLog)
        help_panel = Panel(
            help_text,
            title="📖 Help",
            title_align="left",
            border_style="yellow",
            padding=(0, 1)
        )
        conversation_log.write(help_panel)
        conversation_log.write("")
    
    def _show_context_info(self) -> None:
        """Show current context information."""
        if not self.context_files:
            self._add_system_message("No files in context")
            return
        
        context_info = "📋 Current Context Files:\n"
        for i, file_info in enumerate(self.context_files, 1):
            context_info += f"{i}. {file_info['path']} ({file_info['language']}) - {self._format_size(file_info['size'])}\n"
        
        context_info += f"\nTotal: {len(self.context_files)} files, {len(self.conversation_history)} conversation exchanges"
        
        conversation_log = self.query_one("#conversation_log", TextLog)
        context_panel = Panel(
            context_info,
            title="📋 Context Information",
            title_align="left",
            border_style="cyan",
            padding=(0, 1)
        )
        conversation_log.write(context_panel)
        conversation_log.write("")
    
    # Enhanced action handlers for key bindings
    def action_quit(self) -> None:
        """Quit the application with confirmation."""
        if self.is_processing:
            if hasattr(self.app, 'notify'):
                self.app.notify(
                    "Cannot quit while processing. Stop current operation first.",
                    severity="warning",
                    timeout=3.0
                )
            return
        self.app.exit()
    
    def action_new_chat(self) -> None:
        """Start a new chat with confirmation."""
        if self.conversation_history:
            # In a full implementation, this would show a confirmation dialog
            self._clear_conversation()
        else:
            self._add_system_message("Chat is already empty")
    
    def action_add_file(self) -> None:
        """Show enhanced file picker dialog."""
        self._show_file_picker()
    
    def action_remove_file(self) -> None:
        """Show enhanced file removal dialog."""
        if not self.context_files:
            self._add_system_message("No files in context to remove")
            return
        self._show_file_removal_dialog()
    
    def action_clear_context(self) -> None:
        """Clear all context with confirmation."""
        if self.context_files:
            self._confirm_clear_context()
        else:
            self._add_system_message("Context is already empty")
    
    def action_search_conversation(self) -> None:
        """Show conversation search dialog."""
        self._show_search_dialog()
    
    def action_save_conversation(self) -> None:
        """Save conversation to file."""
        self._save_conversation()
    
    def action_toggle_theme(self) -> None:
        """Toggle between light and dark theme."""
        if THEME_AVAILABLE:
            current_theme = get_theme_config()
            new_theme = "light" if current_theme.mode.value == "dark" else "dark"
            self._change_theme(new_theme)
    
    def action_show_help(self) -> None:
        """Show enhanced help."""
        self._show_help()
    
    def action_focus_input(self) -> None:
        """Focus the input field."""
        self.query_one("#message_input").focus()
    
    def action_next_tab(self) -> None:
        """Switch to next tab."""
        tabs = self.query_one("#main_tabs", TabbedContent)
        tabs.action_next_tab()
    
    def action_previous_tab(self) -> None:
        """Switch to previous tab."""
        tabs = self.query_one("#main_tabs", TabbedContent)
        tabs.action_previous_tab()
    
    def action_toggle_view_mode(self) -> None:
        """Toggle context view mode."""
        self.view_mode = "tree" if self.view_mode == "table" else "table"
        switch = self.query_one("#view_mode_switch", Switch)
        switch.value = self.view_mode == "table"
        self._toggle_context_view()
    
    # Enhanced helper methods
    def _show_file_picker(self) -> None:
        """Show file picker dialog (placeholder for full implementation)."""
        self._add_system_message("💡 Use 'add <filepath>' command to add files")
        self._add_system_message("📁 Example: add ./src/main.py")
    
    def _show_file_removal_dialog(self) -> None:
        """Show file removal dialog (placeholder for full implementation)."""
        self._add_system_message("💡 Use 'remove <filepath>' command to remove files")
        files_list = "\n".join(f"  • {Path(f['path']).name}" for f in self.context_files)
        self._add_system_message(f"📋 Current files:\n{files_list}")
    
    def _confirm_clear_context(self) -> None:
        """Confirm context clearing (placeholder for full implementation)."""
        file_count = len(self.context_files)
        self._add_system_message(f"⚠️ This will remove {file_count} files from context")
        self._add_system_message("💡 Type 'clear' to confirm or use Ctrl+L")
    
    def _show_search_dialog(self) -> None:
        """Show search dialog (placeholder for full implementation)."""
        self._add_system_message("🔍 Search functionality coming soon!")
        self._add_system_message("💡 Use Ctrl+F to search conversations")
    
    def _save_conversation(self) -> None:
        """Save conversation to file (placeholder for full implementation)."""
        if not self.conversation_history:
            self._add_system_message("No conversation to save")
            return
        
        timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
        filename = f"minimax_chat_{timestamp}.md"
        
        self._add_system_message(f"💾 Conversation would be saved as: {filename}")
        self._add_system_message("💡 Full save functionality coming soon!")
    
    def _show_file_context_menu(self, row_key: str) -> None:
        """Show context menu for selected file (placeholder)."""
        if row_key.startswith("file_"):
            file_index = int(row_key.split("_")[1])
            if 0 <= file_index < len(self.context_files):
                file_info = self.context_files[file_index]
                file_name = Path(file_info['path']).name
                self._add_system_message(f"📄 Selected: {file_name}")
                self._add_system_message("💡 Right-click menu coming soon!")
    
    def _delete_selected_context_file(self) -> None:
        """Delete selected context file (placeholder)."""
        self._add_system_message("🗑️ File deletion from selection coming soon!")
    
    def _is_context_focused(self) -> bool:
        """Check if context panel has focus."""
        try:
            focused = self.app.focused
            return focused and focused.id in ["context_table", "context_tree"]
        except:
            return False


# Fallback for when Textual is not available
if not TEXTUAL_AVAILABLE:
    class ChatScreen:
        """Fallback ChatScreen when Textual is not available."""
        
        def __init__(self, *args, **kwargs):
            raise ImportError(
                "Textual is required for TUI mode. Install with: pip install textual>=0.60"
            )


# Export enhanced ChatScreen
__all__ = [
    'ChatScreen',
    'ChatMessage',
    'ContextFileAdded', 
    'ContextFileRemoved'
]
