"""
CLI Application

Main Typer application for HoneyDB MCP CLI.

v2.0: Includes all critical fixes and enhancements.
"""

import asyncio
from pathlib import Path

import typer

from honeydb_ai.controllers.chat_controller import ChatController
from honeydb_ai.controllers.config_controller import ConfigController
from honeydb_ai.controllers.session_controller import SessionController
from honeydb_ai.infrastructure.storage.config_store import INIConfigStore
from honeydb_ai.infrastructure.storage.session_store import JSONSessionStore
from honeydb_ai.infrastructure.ui.console import RichConsoleUI
from honeydb_ai.infrastructure.ui.prompts import create_chat_prompt
from honeydb_ai.services.config_service import ConfigService
from honeydb_ai.services.llm_service import LLMService
from honeydb_ai.services.session_service import SessionService
from honeydb_ai.utils.logging import setup_logging, get_logger


app = typer.Typer(
    name="honeydb-ai",
    help="HoneyDB MCP CLI - Chat with AI models",
    add_completion=False,
)


# Global state
_config_service: ConfigService | None = None
_session_service: SessionService | None = None
_llm_service: LLMService | None = None
_console: RichConsoleUI | None = None
_logger = None


def get_config_service() -> ConfigService:
    """Get or create config service."""
    global _config_service
    if _config_service is None:
        config_path = Path.home() / ".honeydb_ai" / "config.ini"
        config_store = INIConfigStore(config_path)
        _config_service = ConfigService(config_store)
    return _config_service


def get_session_service() -> SessionService:
    """Get or create session service."""
    global _session_service
    if _session_service is None:
        config = get_config_service().load_config()
        sessions_dir = Path(config.sessions_dir).expanduser()
        session_store = JSONSessionStore(sessions_dir)
        _session_service = SessionService(session_store)
    return _session_service


def get_llm_service() -> LLMService:
    """Get or create LLM service."""
    global _llm_service
    if _llm_service is None:
        config = get_config_service().load_config()
        _llm_service = LLMService(config)
    return _llm_service


def get_console() -> RichConsoleUI:
    """Get or create console."""
    global _console
    if _console is None:
        config = get_config_service().load_config()
        _console = RichConsoleUI(theme=config.theme)
    return _console


def initialize_logging() -> None:
    """
    Initialize logging on application startup.

    v2.0 Critical Fix #5: Privacy-first comprehensive logging.
    """
    global _logger
    config = get_config_service().load_config()

    _logger = setup_logging(
        log_file=config.log_file,
        log_level=config.log_level,
        max_size_mb=config.log_max_size_mb,
        backup_count=config.log_backup_count,
    )


def check_first_run() -> bool:
    """
    Check if this is the first run (no config file exists).

    Returns:
        True if first run
    """
    config_service = get_config_service()
    return not config_service.config_exists()


@app.command()
def chat(
    session_id: str = typer.Option(None, "--session", "-s", help="Session ID to resume"),
    new: bool = typer.Option(False, "--new", "-n", help="Start a new session"),
) -> None:
    """
    Start an interactive chat session.

    v2.0 Critical Fixes:
    - Ctrl+C cancellation (Fix #2)
    - Tool call visibility (Fix #3)
    - Terminal capability detection (Fix #4)
    """
    # Initialize logging
    initialize_logging()

    # Check for first run
    if check_first_run():
        console = get_console()
        config_controller = ConfigController(get_config_service(), console)
        config_controller.interactive_setup()

    # Get services and controllers
    console = get_console()
    config_service = get_config_service()
    session_service = get_session_service()
    llm_service = get_llm_service()

    # Get config for verbose_tool_calls setting
    config = config_service.load_config()

    # Create controllers
    config_controller = ConfigController(config_service, console)
    session_controller = SessionController(session_service, console)

    chat_controller = ChatController(
        llm_service,
        session_service,
        console,
        verbose_tool_calls=config.verbose_tool_calls,
        config_controller=config_controller,
        session_controller=session_controller,
    )

    # Handle session
    if new:
        session = session_controller.create_session()
        chat_controller.set_session(session)
    elif session_id:
        try:
            session = session_controller.load_session(session_id)
            chat_controller.set_session(session)
        except Exception as e:
            console.print_error(str(e))
            raise typer.Exit(1)
    else:
        # Create new session if none specified
        session = session_controller.create_session()
        chat_controller.set_session(session)

    # Create prompt
    history_file = Path.home() / ".honeydb_ai" / "history.txt"
    prompt = create_chat_prompt(history_file)

    # Run chat loop
    try:
        # Use async version of prompt to avoid event loop conflicts
        asyncio.run(chat_controller.run_chat_loop(
            prompt_async_func=lambda: prompt.prompt_async("> ")
        ))
    except KeyboardInterrupt:
        console.print("\nExiting...", style="dim")
    except Exception as e:
        console.print_error(f"Chat error: {e}")
        raise typer.Exit(1)


@app.command()
def config(
    show: bool = typer.Option(False, "--show", help="Show current configuration"),
    set_api_key: str = typer.Option(None, "--set-api-key", help="Set API key for provider (provider:key)"),
    set_provider: str = typer.Option(None, "--set-provider", help="Set default provider"),
    set_model: str = typer.Option(None, "--set-model", help="Set default model"),
    set_temperature: float = typer.Option(None, "--set-temperature", help="Set temperature"),
    set_theme: str = typer.Option(None, "--set-theme", help="Set theme (auto/dark/light)"),
) -> None:
    """
    Manage configuration.

    v2.0 Major Enhancement #8: Configuration hot-reload support.
    """
    initialize_logging()

    console = get_console()
    config_service = get_config_service()
    config_controller = ConfigController(config_service, console)

    # Load config
    cfg = config_controller.load_config()

    # Handle operations
    if set_api_key:
        if ":" not in set_api_key:
            console.print_error("API key must be in format: provider:key")
            raise typer.Exit(1)
        provider, key = set_api_key.split(":", 1)
        config_controller.set_api_key(provider, key)

    elif set_provider:
        config_controller.set_default_provider(set_provider)

    elif set_model:
        config_controller.set_default_model(set_model)

    elif set_temperature is not None:
        config_controller.set_temperature(set_temperature)

    elif set_theme:
        config_controller.set_theme(set_theme)

    elif show or True:  # Default action
        config_controller.display_config(cfg)


if __name__ == "__main__":
    app()
