"""
Main application class for Socrates AI - Command-Based CLI Interface
"""

import datetime
import getpass
import os
import signal
import subprocess
import sys
import time
import webbrowser
from pathlib import Path
from typing import Any, Dict, Optional

from colorama import Fore, Style

from socratic_system.models import ProjectContext, User
from socratic_system.orchestration import AgentOrchestrator
from socratic_system.ui.command_handler import CommandHandler
from socratic_system.ui.commands import (  # Analytics commands; Code commands; Finalize commands; Collaboration commands; Skills commands; Session commands; Conversation commands; Debug commands; Document commands; System commands; Note commands; Project commands; Statistics commands; User commands; Subscription commands; GitHub commands
    AdvanceCommand,
    AnalyticsAnalyzeCommand,
    AnalyticsBreakdownCommand,
    AnalyticsRecommendCommand,
    AnalyticsStatusCommand,
    AnalyticsSummaryCommand,
    AnalyticsTrendsCommand,
    BackCommand,
    ChatCommand,
    ClearCommand,
    CodeDocsCommand,
    CodeGenerateCommand,
    CollabAddCommand,
    CollabListCommand,
    CollabRemoveCommand,
    CollabRoleCommand,
    ConvSearchCommand,
    ConvSummaryCommand,
    DebugCommand,
    DocImportCommand,
    DocImportDirCommand,
    DocImportUrlCommand,
    DocListCommand,
    DocPasteCommand,
    DocsCommand,
    DoneCommand,
    ExitCommand,
    ExplainCommand,
    FileDeleteCommand,
    FinalizeDocsCommand,
    FinalizeGenerateCommand,
    GithubImportCommand,
    GithubPullCommand,
    GithubPushCommand,
    GithubSyncCommand,
    HelpCommand,
    HintCommand,
    InfoCommand,
    LLMCommand,
    LogsCommand,
    MaturityCommand,
    MaturityHistoryCommand,
    MaturityStatusCommand,
    MaturitySummaryCommand,
    MenuCommand,
    ModeCommand,
    ModelCommand,
    NLUDisableCommand,
    NLUEnableCommand,
    NLUStatusCommand,
    NoteAddCommand,
    NoteDeleteCommand,
    NoteListCommand,
    NoteSearchCommand,
    ProjectAnalyzeCommand,
    ProjectArchiveCommand,
    ProjectCreateCommand,
    ProjectDeleteCommand,
    ProjectDiffCommand,
    ProjectFixCommand,
    ProjectListCommand,
    ProjectLoadCommand,
    ProjectProgressCommand,
    ProjectRestoreCommand,
    ProjectReviewCommand,
    ProjectStatsCommand,
    ProjectStatusCommand,
    ProjectTestCommand,
    ProjectValidateCommand,
    PromptCommand,
    RollbackCommand,
    SearchCommand,
    SkillsListCommand,
    SkillsSetCommand,
    SkippedCommand,
    StatusCommand,
    SubscriptionCompareCommand,
    SubscriptionDowngradeCommand,
    SubscriptionStatusCommand,
    SubscriptionTestingModeCommand,
    SubscriptionUpgradeCommand,
    UserArchiveCommand,
    UserCreateCommand,
    UserDeleteCommand,
    UserLoginCommand,
    UserLogoutCommand,
    UserRestoreCommand,
)
from socratic_system.ui.context_display import ContextDisplay
from socratic_system.ui.navigation import NavigationStack
from socratic_system.ui.nlu_handler import NLUHandler, SuggestionDisplay
from socratic_system.utils.logger import get_logger as get_debug_logger
from socratic_system.utils.logger import reset_logger, set_debug_mode

# ============================================================================
# Command Registry Pattern - Consolidated command registration
# ============================================================================
# Registry of (CommandClass, aliases) tuples
# This eliminates ~136 lines of repetitive register_command calls
COMMAND_REGISTRY = [
    # System commands
    (HelpCommand, ["h", "?"]),
    (ExitCommand, ["quit", "q"]),
    (BackCommand, []),
    (MenuCommand, []),
    (StatusCommand, []),
    (ClearCommand, ["cls"]),
    (PromptCommand, []),
    (InfoCommand, []),
    (ModelCommand, []),
    (LLMCommand, ["llm"]),
    # NLU control commands
    (NLUEnableCommand, []),
    (NLUDisableCommand, []),
    (NLUStatusCommand, []),
    # User commands
    (UserLoginCommand, []),
    (UserCreateCommand, []),
    (UserLogoutCommand, []),
    (UserArchiveCommand, []),
    (UserDeleteCommand, []),
    (UserRestoreCommand, []),
    # Subscription commands
    (SubscriptionStatusCommand, []),
    (SubscriptionUpgradeCommand, []),
    (SubscriptionDowngradeCommand, []),
    (SubscriptionCompareCommand, []),
    (SubscriptionTestingModeCommand, []),
    # Project commands
    (ProjectCreateCommand, []),
    (ProjectLoadCommand, []),
    (ProjectListCommand, []),
    (ProjectArchiveCommand, []),
    (ProjectRestoreCommand, []),
    (ProjectDeleteCommand, []),
    # Project analysis/validation commands
    (ProjectAnalyzeCommand, []),
    (ProjectTestCommand, []),
    (ProjectValidateCommand, []),
    (ProjectFixCommand, []),
    (ProjectReviewCommand, []),
    (ProjectDiffCommand, []),
    # GitHub commands
    (GithubImportCommand, []),
    (GithubPullCommand, []),
    (GithubPushCommand, []),
    (GithubSyncCommand, []),
    # Session commands
    (ChatCommand, []),
    (ModeCommand, []),
    (DoneCommand, []),
    (AdvanceCommand, ["phase"]),
    (RollbackCommand, ["phase-back"]),
    (HintCommand, []),
    (SkippedCommand, []),
    # Code commands
    (CodeGenerateCommand, []),
    (CodeDocsCommand, []),
    # Finalize commands (project type-agnostic artifact generation)
    (FinalizeGenerateCommand, []),
    (FinalizeDocsCommand, []),
    # Collaboration commands
    (CollabAddCommand, []),
    (CollabRemoveCommand, []),
    (CollabListCommand, []),
    (CollabRoleCommand, []),
    # Skills commands
    (SkillsSetCommand, []),
    (SkillsListCommand, []),
    # Document commands
    (DocsCommand, []),
    (DocImportCommand, []),
    (DocImportDirCommand, []),
    (DocImportUrlCommand, []),
    (DocListCommand, []),
    (DocPasteCommand, []),
    # File commands
    (FileDeleteCommand, []),
    # Note commands
    (NoteAddCommand, []),
    (NoteListCommand, []),
    (NoteSearchCommand, []),
    (NoteDeleteCommand, []),
    # Conversation commands
    (ConvSearchCommand, []),
    (ConvSummaryCommand, []),
    # Statistics commands
    (ProjectStatsCommand, []),
    (ProjectProgressCommand, []),
    (ProjectStatusCommand, []),
    # Maturity tracking commands
    (MaturityCommand, []),
    (MaturitySummaryCommand, []),
    (MaturityHistoryCommand, []),
    (MaturityStatusCommand, []),
    # Debug commands
    (DebugCommand, []),
    (LogsCommand, []),
    # Query/Answer commands
    (ExplainCommand, []),
    (SearchCommand, []),
]

# Analytics commands (require orchestrator injection)
ANALYTICS_COMMANDS = [
    (AnalyticsAnalyzeCommand, ["aa"]),
    (AnalyticsRecommendCommand, ["ar"]),
    (AnalyticsTrendsCommand, ["at"]),
    (AnalyticsSummaryCommand, ["as"]),
    (AnalyticsBreakdownCommand, ["abd"]),
    (AnalyticsStatusCommand, ["ast"]),
]


# ============================================================================
# UI STATE MANAGEMENT
# ============================================================================


class UIState:
    """Manages UI state and display context for the application.

    Handles:
    - Current user and project context
    - Display elements (analytics, maturity, context info)
    - Navigation state and history
    - Session lifecycle management
    """

    def __init__(self):
        """Initialize UI state."""
        self.current_user: Optional[User] = None
        self.current_project: Optional[ProjectContext] = None
        self.context_display: Optional[Any] = None
        self.maturity_display: Optional[Any] = None
        self.analytics_display: Optional[Any] = None
        self.session_active: bool = False

    def set_current_user(self, user: User) -> None:
        """Set the current authenticated user."""
        self.current_user = user

    def set_current_project(self, project: ProjectContext) -> None:
        """Set the current active project."""
        self.current_project = project

    def is_authenticated(self) -> bool:
        """Check if user is authenticated."""
        return self.current_user is not None

    def clear_session(self) -> None:
        """Clear all session state."""
        self.current_user = None
        self.current_project = None
        self.session_active = False


# ============================================================================
# AUTHENTICATION MANAGER
# ============================================================================


class AuthenticationManager:
    """Manages user authentication and API key handling.

    Responsibilities:
    - Prompting for authentication credentials
    - Managing Claude API keys
    - User login and logout
    - Session persistence
    """

    def __init__(self):
        """Initialize authentication manager."""
        self.api_key: Optional[str] = None
        self.authenticated: bool = False

    def get_api_key(self) -> Optional[str]:
        """Retrieve Claude API key from environment or user input."""
        # Implementation moved from main_app._get_api_key
        return self.api_key

    def authenticate_user(self) -> bool:
        """Authenticate user with credentials.

        Returns:
            True if authentication successful, False otherwise
        """
        # Implementation moved from main_app._authenticate_user
        return self.authenticated


# ============================================================================
# COMMAND REGISTRATION MANAGER
# ============================================================================


class CommandRegistrationManager:
    """Manages command registration and command handler setup.

    Responsibilities:
    - Registering all available commands
    - Organizing commands by category
    - Setting up command handler
    - Managing command lifecycle
    """

    @staticmethod
    def register_all_commands(command_handler: CommandHandler) -> None:
        """Register all available commands with the command handler.

        Organizes commands into logical groups:
        - Project management commands
        - Document handling commands
        - Code generation and validation
        - Analytics and monitoring
        - User and collaboration management
        - System and navigation commands

        Args:
            command_handler: CommandHandler instance to register commands with
        """
        # Implementation moved from main_app._register_commands
        pass


# ============================================================================
# RESULT HANDLER
# ============================================================================


class CommandResultHandler:
    """Handles command execution results and their consequences.

    Responsibilities:
    - Processing command results
    - Updating application state based on results
    - Displaying appropriate messages to users
    - Managing session lifecycle
    - Navigation context changes
    """

    def __init__(self, ui_state: UIState):
        """Initialize result handler with UI state reference.

        Args:
            ui_state: UIState instance to update
        """
        self.ui_state = ui_state

    def handle_result(self, result: Dict[str, Any]) -> bool:
        """Process a command result.

        Args:
            result: Command execution result

        Returns:
            True if application should continue, False to exit
        """
        # Implementation moved from main_app._handle_command_result
        return True


# ============================================================================
# FRONTEND MANAGER
# ============================================================================


class FrontendManager:
    """Manages optional frontend application lifecycle.

    Responsibilities:
    - Starting and stopping web frontend
    - Managing frontend process
    - Handling frontend configuration
    """

    def __init__(self):
        """Initialize frontend manager."""
        self.frontend_process: Optional[Any] = None

    def start_frontend(self) -> bool:
        """Start the web frontend application.

        Returns:
            True if frontend started successfully, False otherwise
        """
        # Implementation moved from main_app._start_frontend
        return False

    def stop_frontend(self) -> None:
        """Stop the running web frontend."""
        # Implementation moved from main_app._stop_frontend
        pass


class SocraticRAGSystem:
    """Main application class for Socrates AI with command-based interface"""

    def __init__(self, start_frontend: bool = False):
        """Initialize the application

        Args:
            start_frontend: If True, also start the React frontend dev server
        """
        self.orchestrator: Optional[AgentOrchestrator] = None
        self.current_user: Optional[User] = None
        self.current_project: Optional[ProjectContext] = None
        self.session_start: datetime.datetime = datetime.datetime.now()

        # Command system components
        self.command_handler: Optional[CommandHandler] = None
        self.nav_stack: Optional[NavigationStack] = None
        self.context_display: Optional[ContextDisplay] = None
        self.nlu_handler: Optional[NLUHandler] = None

        # Frontend process management
        self.start_frontend = start_frontend
        self.frontend_process: Optional[subprocess.Popen] = None
        self.api_process: Optional[subprocess.Popen] = None

        # Initialize debug logger
        self.logger = get_debug_logger("main_app")

        # Setup signal handlers for graceful shutdown
        signal.signal(signal.SIGINT, self._handle_shutdown)
        signal.signal(signal.SIGTERM, self._handle_shutdown)

    def _handle_shutdown(self, signum, frame):
        """Handle graceful shutdown on Ctrl+C"""
        print(f"\n\n{Fore.YELLOW}Shutting down...{Style.RESET_ALL}")
        self._stop_frontend()
        sys.exit(0)

    def _start_frontend(self) -> bool:
        """Start the React frontend dev server

        Returns:
            True if frontend started successfully, False otherwise
        """
        if not self.start_frontend:
            return True

        print(f"{Fore.CYAN}[Frontend] Starting React dev server...{Style.RESET_ALL}")

        try:
            frontend_dir = Path.cwd() / "socrates-frontend"

            # Check if frontend directory exists
            if not frontend_dir.exists():
                print(
                    f"{Fore.RED}[Frontend] Error: socrates-frontend directory not found{Style.RESET_ALL}"
                )
                return False

            # Check if node_modules exists
            if not (frontend_dir / "node_modules").exists():
                print(f"{Fore.YELLOW}[Frontend] Installing dependencies...{Style.RESET_ALL}")
                result = subprocess.run(
                    ["npm", "install", "--legacy-peer-deps"],
                    cwd=frontend_dir,
                    capture_output=True,
                    text=True,
                )
                if result.returncode != 0:
                    print(f"{Fore.RED}[Frontend] Failed to install dependencies{Style.RESET_ALL}")
                    return False

            # Start frontend development server
            self.frontend_process = subprocess.Popen(
                ["npm", "run", "dev"],
                cwd=frontend_dir,
                stdout=subprocess.PIPE,
                stderr=subprocess.STDOUT,
                text=True,
                env={**os.environ, "VITE_API_URL": "http://localhost:8000"},
            )

            time.sleep(3)  # Give it a moment to start

            if self.frontend_process.poll() is None:
                print(
                    f"{Fore.GREEN}[Frontend] Dev server started (PID: {self.frontend_process.pid}){Style.RESET_ALL}"
                )
                print(f"{Fore.CYAN}[Frontend] Access at: http://localhost:5173{Style.RESET_ALL}")

                # Open browser automatically
                try:
                    time.sleep(1)  # Extra moment to ensure server is fully ready
                    print(f"{Fore.CYAN}[Frontend] Opening browser...{Style.RESET_ALL}")
                    webbrowser.open("http://localhost:5173")
                except Exception as e:
                    print(
                        f"{Fore.YELLOW}[Frontend] Could not open browser automatically: {e}{Style.RESET_ALL}"
                    )
                    print(
                        f"{Fore.YELLOW}[Frontend] Please open manually: http://localhost:5173{Style.RESET_ALL}"
                    )

                return True
            else:
                print(f"{Fore.RED}[Frontend] Failed to start development server{Style.RESET_ALL}")
                return False

        except Exception as e:
            print(f"{Fore.RED}[Frontend] Error starting frontend: {e}{Style.RESET_ALL}")
            return False

    def _stop_frontend(self) -> None:
        """Stop the frontend development server"""
        if self.frontend_process and self.frontend_process.poll() is None:
            print(f"{Fore.YELLOW}[Frontend] Stopping dev server...{Style.RESET_ALL}")
            try:
                self.frontend_process.terminate()
                self.frontend_process.wait(timeout=5)
                print(f"{Fore.GREEN}[Frontend] Dev server stopped{Style.RESET_ALL}")
            except subprocess.TimeoutExpired:
                self.frontend_process.kill()
            except Exception as e:
                print(f"{Fore.RED}[Frontend] Error stopping frontend: {e}{Style.RESET_ALL}")

    def start(self) -> None:
        """Start the Socrates AI"""
        self._print_banner()

        # Start frontend if requested
        if self.start_frontend:
            if not self._start_frontend():
                print(f"{Fore.YELLOW}Continuing without frontend...{Style.RESET_ALL}")

        # Reset logger singleton to clear old handlers and use new rotation handler
        reset_logger()
        # Reinitialize logger after reset
        self.logger = get_debug_logger("main_app")

        # Disable debug mode by default (user can toggle with /debug command)
        set_debug_mode(False)

        # Get API key or choose authentication mode
        api_key = self._get_api_key()
        if not api_key:
            print(f"{Fore.RED}No API key provided. Exiting...")
            self._stop_frontend()
            return

        try:
            # Initialize orchestrator
            print(f"\n{Fore.YELLOW}Initializing system...{Style.RESET_ALL}")
            # In subscription mode, use a placeholder API key - actual auth happens during user login
            if api_key == "subscription_mode":
                # For subscription mode, we'll use a dummy key initially
                # It will be validated during user authentication
                self.orchestrator = AgentOrchestrator("subscription_placeholder_key")
            else:
                self.orchestrator = AgentOrchestrator(api_key)

            # Initialize command system components
            self.command_handler = CommandHandler()
            self.nav_stack = NavigationStack()
            self.nav_stack.push("main_menu", {})  # Initialize with main menu as root context
            self.logger.debug("Navigation stack initialized with main_menu as root")
            self.context_display = ContextDisplay()

            # Register all commands
            self._register_commands()

            # Authenticate user
            if not self._authenticate_user():
                return

            # Enable NLU after login
            self.nlu_handler = NLUHandler(self.orchestrator.claude_client, self.command_handler)
            print(f"{Fore.GREEN}[OK] Natural language understanding enabled{Style.RESET_ALL}")

            # Start command loop
            self._command_loop()

        except Exception as e:
            print(f"{Fore.RED}System error: {e}{Style.RESET_ALL}")

    def _print_banner(self) -> None:
        """Display the application banner"""
        print(f"{Fore.CYAN}{Style.BRIGHT}")
        print("╔═══════════════════════════════════════════════╗")
        print("║             Socrates RAG System               ║")
        print("║Οὐδὲν οἶδα, οὔτε διδάσκω τι, ἀλλὰ διαπορῶ μόνον║")
        print("╚═══════════════════════════════════════════════╝")
        print(f"{Style.RESET_ALL}")

    def _get_api_key(self) -> Optional[str]:
        """Get Claude API key from environment or user input"""
        api_key = os.getenv("API_KEY_CLAUDE")
        if not api_key:
            print(f"\n{Fore.CYAN}API Configuration{Style.RESET_ALL}")
            print(f"{Fore.YELLOW}Choose how to authenticate with Claude:{Style.RESET_ALL}")
            print("1. Use API Key directly")
            print("2. Use Subscription (requires valid account)")

            choice = input(f"\n{Fore.WHITE}Select option (1 or 2): ").strip()

            if choice == "2":
                # Subscription mode - will be handled by authenticating user first
                print(
                    f"{Fore.CYAN}Using subscription mode - authenticate with your account{Style.RESET_ALL}"
                )
                # Store a marker that we're in subscription mode
                os.environ["SOCRATES_SUBSCRIPTION_MODE"] = "1"
                # Return a placeholder - actual API key will be obtained from orchestrator
                return "subscription_mode"
            else:
                # API Key mode
                print(
                    f"{Fore.CYAN}Paste your Claude API key (or set API_KEY_CLAUDE env var):{Style.RESET_ALL}"
                )
                api_key = getpass.getpass("Claude API Key: ")
                if api_key:
                    os.environ["SOCRATES_SUBSCRIPTION_MODE"] = "0"
        return api_key

    def _authenticate_user(self) -> bool:
        """Handle user login or registration"""
        print(f"\n{Fore.CYAN}Authentication{Style.RESET_ALL}\n")

        while True:
            print(f"{Fore.YELLOW}Options:{Style.RESET_ALL}")
            print("1. Login with existing account (/user login)")
            print("2. Create new account (/user create)")
            print("3. Exit (/exit)")

            choice = input(f"\n{Fore.WHITE}Choose option (1-3): ").strip()

            if choice == "1" or choice.startswith("/user login"):
                result = UserLoginCommand().execute([], self._get_context())
                if result["status"] == "success":
                    self.current_user = result["data"]["user"]
                    self.context_display.set_context(user=self.current_user)
                    self._apply_testing_mode_if_enabled()
                    return True
                else:
                    if result.get("message"):
                        print(result["message"])

            elif choice == "2" or choice.startswith("/user create"):
                result = UserCreateCommand().execute([], self._get_context())
                if result["status"] == "success":
                    self.current_user = result["data"]["user"]
                    self.context_display.set_context(user=self.current_user)
                    self._apply_testing_mode_if_enabled()
                    return True
                else:
                    if result.get("message"):
                        print(result["message"])

            elif choice == "3" or choice == "/exit":
                print(f"\n{Fore.GREEN}Thank you for using Socrates AI")
                print("..τῷ Ἀσκληπιῷ ὀφείλομεν ἀλεκτρυόνα, ἀπόδοτε καὶ μὴ ἀμελήσετε...\n")
                return False

            else:
                print(f"{Fore.RED}Invalid choice. Please try again.{Style.RESET_ALL}")

    def _apply_testing_mode_if_enabled(self) -> None:
        """Enable testing mode for current user if --testing flag was provided."""
        if os.getenv("SOCRATES_TESTING_MODE") == "1" and self.current_user:
            if not self.current_user.testing_mode:
                self.current_user.testing_mode = True
                self.orchestrator.database.save_user(self.current_user)
                print(f"\n{Fore.GREEN}[OK] Testing mode ENABLED{Style.RESET_ALL}")
                print(f"{Fore.YELLOW}All monetization restrictions bypassed!{Style.RESET_ALL}\n")

    def _register_commands(self) -> None:
        """Register all available commands using registry pattern"""
        # Register standard commands from registry
        for command_class, aliases in COMMAND_REGISTRY:
            command_instance = command_class()
            if aliases:
                self.command_handler.register_command(command_instance, aliases=aliases)
            else:
                self.command_handler.register_command(command_instance)

        # Register analytics commands (require orchestrator injection)
        for command_class, aliases in ANALYTICS_COMMANDS:
            command_instance = command_class(self.orchestrator)
            if aliases:
                self.command_handler.register_command(command_instance, aliases=aliases)
            else:
                self.command_handler.register_command(command_instance)

    def _handle_command_result(self, result: Dict[str, Any]) -> bool:
        """
        Handle command execution result and display appropriate messages.

        Args:
            result: Command result dictionary with status and message

        Returns:
            True if command loop should continue, False if exit requested
        """
        status = result["status"]

        if status == "exit":
            return False

        # Display message if present
        if result.get("message"):
            self._display_status_message(status, result["message"])

        # Handle success status with data processing
        if status == "success":
            self._handle_success_result(result.get("data", {}))
        elif status not in ("info", "idle", "error"):
            # Unknown status
            print(f"{Fore.YELLOW}Command executed with status: {status}{Style.RESET_ALL}")

        return True

    def _display_status_message(self, status: str, message: str) -> None:
        """Display message based on status type"""
        if status == "unknown":
            return  # Don't duplicate unknown messages
        print(message)

    def _handle_success_result(self, data: Dict[str, Any]) -> None:
        """Handle success status data and navigation"""
        # Handle project entry (push to navigation stack)
        project = data.get("project")
        if project:
            self._handle_project_entry(project)

        # Handle navigation context changes (from /back, /menu commands)
        nav_context = data.get("nav_context")
        if nav_context:
            self._handle_nav_context(nav_context)

        # Check if session ended (done command, menu command, back command)
        if data.get("session_ended"):
            self._clear_session()

    def _handle_project_entry(self, project) -> None:
        """Handle entering a project context"""
        if self.nav_stack:
            self.nav_stack.push("project_view", {"project_id": project.project_id})
            self.logger.debug(f"Entered project context: {project.name} (ID: {project.project_id})")

    def _handle_nav_context(self, nav_context: str) -> None:
        """Handle navigation context changes"""
        if nav_context == "main_menu":
            self.current_project = None
            self.context_display.set_context(clear_project=True)
            self.logger.debug("Returned to main_menu context")

    def _clear_session(self) -> None:
        """Clear session data when session ends"""
        self.current_project = None
        self.context_display.set_context(clear_project=True)
        self.logger.debug("Session ended - cleared project and context display")

    def _command_loop(self) -> None:
        """Main command processing loop"""
        while True:
            try:
                # Display context
                prompt = self.context_display.get_prompt()
                user_input = input(prompt).strip()

                if not user_input:
                    continue

                # Execute command (with NLU support)
                result = self._process_input_with_nlu(user_input, self._get_context())

                # Handle result
                if not self._handle_command_result(result):
                    break

            except KeyboardInterrupt:
                print(f"\n{Fore.YELLOW}Interrupted. Type '/exit' to quit.{Style.RESET_ALL}")
            except Exception as e:
                print(f"{Fore.RED}Unexpected error: {e}{Style.RESET_ALL}")

    def _process_input_with_nlu(self, user_input: str, context: Dict[str, Any]) -> Dict[str, Any]:
        """Process input with NLU support"""
        # Skip NLU if not initialized or input starts with /
        if not self.nlu_handler or self.nlu_handler.should_skip_nlu(user_input):
            return self.command_handler.execute(user_input, context)

        # Interpret with NLU
        nlu_result = self.nlu_handler.interpret(user_input, context)

        if nlu_result["status"] == "success":
            # High confidence - execute directly
            command = nlu_result["command"]
            if nlu_result.get("message"):
                print(nlu_result["message"])
            return self.command_handler.execute(command, context)

        elif nlu_result["status"] == "suggestions":
            # Medium confidence - show suggestions
            if nlu_result.get("message"):
                print(nlu_result["message"])
            suggestions = nlu_result.get("suggestions", [])
            selected = SuggestionDisplay.show_suggestions(suggestions)

            if selected:
                print(f"{Fore.CYAN}[NLU] Executing: {selected}{Style.RESET_ALL}")
                return self.command_handler.execute(selected, context)
            return {"status": "idle"}

        else:  # no_match or error
            return {
                "status": "error",
                "message": nlu_result.get("message", "Couldn't understand that."),
            }

    def _get_context(self) -> Dict[str, Any]:
        """Get the current application context for commands"""
        return {
            "user": self.current_user,
            "project": self.current_project,
            "orchestrator": self.orchestrator,
            "nav_stack": self.nav_stack,
            "app": self,
        }


def main():
    """Main entry point for the application

    Command line arguments:
        --frontend or -f: Start the React frontend dev server along with the CLI
        --help or -h: Show this help message

    Examples:
        python -m socratic_system.ui.main_app                 # CLI only
        python -m socratic_system.ui.main_app --frontend      # CLI + Frontend
        python -m socratic_system.ui.main_app -f              # CLI + Frontend (short form)
    """
    # Check for command line arguments
    start_frontend = "--frontend" in sys.argv or "-f" in sys.argv
    show_help = "--help" in sys.argv or "-h" in sys.argv

    if show_help:
        print(main.__doc__)
        sys.exit(0)

    # Create and start application
    app = SocraticRAGSystem(start_frontend=start_frontend)
    app.start()


if __name__ == "__main__":
    main()
