"""
Config Controller

Controller for configuration management operations.

v2.0: Includes hot-reload support.
"""

from honeydb_ai.domain.models import Config
from honeydb_ai.infrastructure.ui.console import RichConsoleUI
from honeydb_ai.services.config_service import ConfigService
from honeydb_ai.utils.formatters import format_config_value
from honeydb_ai.utils.logging import get_logger


class ConfigController:
    """
    Controller for configuration management.

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

    def __init__(self, config_service: ConfigService, console: RichConsoleUI):
        """
        Initialize config controller.

        Args:
            config_service: Config service instance
            console: Console UI instance
        """
        self.config_service = config_service
        self.console = console
        self.logger = get_logger()

    def load_config(self) -> Config:
        """
        Load configuration.

        Returns:
            Config object
        """
        try:
            config = self.config_service.load_config()
            self.logger.info("Configuration loaded")
            return config
        except Exception as e:
            self.console.print_error(f"Failed to load configuration: {e}")
            raise

    def save_config(self, config: Config) -> None:
        """
        Save configuration.

        Args:
            config: Configuration to save
        """
        try:
            self.config_service.save_config(config)
            self.console.print_success("Configuration saved")
        except Exception as e:
            self.console.print_error(f"Failed to save configuration: {e}")
            raise

    def display_config(self, config: Config) -> None:
        """
        Display current configuration.

        Args:
            config: Configuration to display
        """
        # Configuration file path
        config_path = self.config_service.get_config_path()
        self.console.print(f"\nConfiguration file: {config_path}", style="dim")
        self.console.print("")

        # HoneyDB MCP Configuration
        honeydb_status_id = "✓ Set" if config.honeydb_api_id else "✗ Not set"
        honeydb_status_key = "✓ Set" if config.honeydb_api_key else "✗ Not set"

        honeydb_config = [
            f"API ID: {format_config_value(config.honeydb_api_id, is_sensitive=True)} ({honeydb_status_id})",
            f"API Key: {format_config_value(config.honeydb_api_key, is_sensitive=True)} ({honeydb_status_key})",
            f"MCP Server URL: {config.mcp_server_url}",
        ]

        self.console.print_panel(
            "\n".join(honeydb_config),
            title="HoneyDB MCP Configuration",
            style="info"
        )

        # LLM Configuration
        openai_status = "✓ Set" if config.openai_api_key else "✗ Not set"
        anthropic_status = "✓ Set" if config.anthropic_api_key else "✗ Not set"
        gemini_status = "✓ Set" if config.gemini_api_key else "✗ Not set"

        llm_config = [
            f"Default Provider: {config.default_provider}",
            f"Default Model: {config.default_model}",
            f"Temperature: {config.temperature}",
            f"Max Tokens: {config.max_tokens or 'Not set'}",
            "",
            "API Keys:",
            f"  OpenAI: {format_config_value(config.openai_api_key, is_sensitive=True)} ({openai_status})",
            f"  Anthropic: {format_config_value(config.anthropic_api_key, is_sensitive=True)} ({anthropic_status})",
            f"  Gemini: {format_config_value(config.gemini_api_key, is_sensitive=True)} ({gemini_status})",
        ]

        self.console.print_panel(
            "\n".join(llm_config),
            title="LLM Configuration",
            style="info"
        )

        # Session Configuration
        session_config = [
            f"Auto-save: {format_config_value(config.auto_save)}",
            f"Sessions Directory: {config.sessions_dir}",
        ]

        self.console.print_panel(
            "\n".join(session_config),
            title="Session Configuration",
            style="info"
        )

        # UI Configuration
        ui_config = [
            f"Theme: {config.theme}",
            f"Markdown: {format_config_value(config.markdown_enabled)}",
            f"Syntax Highlighting: {format_config_value(config.syntax_highlighting)}",
            f"Verbose Tool Calls: {format_config_value(config.verbose_tool_calls)}",
        ]

        self.console.print_panel(
            "\n".join(ui_config),
            title="UI Configuration",
            style="info"
        )

        # Logging Configuration (v2.0)
        logging_config = [
            f"Log Level: {config.log_level}",
            f"Log File: {config.log_file}",
            f"Max Size: {config.log_max_size_mb} MB",
            f"Backup Count: {config.log_backup_count}",
        ]

        self.console.print_panel(
            "\n".join(logging_config),
            title="Logging Configuration",
            style="info"
        )

    def set_api_key(self, provider: str, api_key: str | None = None) -> Config:
        """
        Set API key for a provider.

        Args:
            provider: Provider name
            api_key: API key (will prompt if not provided)

        Returns:
            Updated config
        """
        if not api_key:
            api_key = self.console.prompt(
                f"Enter {provider} API key",
                default=""
            )

        if not api_key or not api_key.strip():
            self.console.print_warning("No API key provided")
            return self.load_config()

        try:
            config = self.config_service.update_api_key(provider, api_key)
            self.console.print_success(f"{provider} API key updated")
            return config
        except Exception as e:
            self.console.print_error(f"Failed to update API key: {e}")
            raise

    def set_default_provider(self, provider: str) -> Config:
        """
        Set default LLM provider.

        Args:
            provider: Provider name

        Returns:
            Updated config
        """
        try:
            config = self.config_service.update_default_provider(provider)
            self.console.print_success(f"Default provider set to: {provider}")
            return config
        except Exception as e:
            self.console.print_error(f"Failed to update default provider: {e}")
            raise

    def set_default_model(self, model: str) -> Config:
        """
        Set default model.

        Args:
            model: Model identifier

        Returns:
            Updated config
        """
        try:
            config = self.config_service.update_default_model(model)
            self.console.print_success(f"Default model set to: {model}")
            return config
        except Exception as e:
            self.console.print_error(f"Failed to update default model: {e}")
            raise

    def set_temperature(self, temperature: float) -> Config:
        """
        Set temperature.

        Args:
            temperature: Temperature value

        Returns:
            Updated config
        """
        try:
            config = self.config_service.update_temperature(temperature)
            self.console.print_success(f"Temperature set to: {temperature}")
            return config
        except Exception as e:
            self.console.print_error(f"Failed to update temperature: {e}")
            raise

    def set_max_tokens(self, max_tokens: int | None) -> Config:
        """
        Set max tokens.

        Args:
            max_tokens: Max tokens value or None

        Returns:
            Updated config
        """
        try:
            config = self.config_service.update_max_tokens(max_tokens)
            self.console.print_success(f"Max tokens set to: {max_tokens or 'Not set'}")
            return config
        except Exception as e:
            self.console.print_error(f"Failed to update max tokens: {e}")
            raise

    def set_theme(self, theme: str) -> Config:
        """
        Set UI theme.

        Args:
            theme: Theme setting (auto, dark, light)

        Returns:
            Updated config
        """
        try:
            config = self.config_service.update_theme(theme)
            self.console.print_success(f"Theme set to: {theme}")
            self.console.print_warning("Restart the application for theme changes to take effect")
            return config
        except Exception as e:
            self.console.print_error(f"Failed to update theme: {e}")
            raise

    def set_log_level(self, log_level: str) -> Config:
        """
        Set logging level.

        v2.0: Logging configuration.

        Args:
            log_level: Log level (DEBUG, INFO, WARNING, ERROR)

        Returns:
            Updated config
        """
        try:
            config = self.config_service.update_log_level(log_level)
            self.console.print_success(f"Log level set to: {log_level}")
            return config
        except Exception as e:
            self.console.print_error(f"Failed to update log level: {e}")
            raise

    def set_verbose_tool_calls(self, verbose: bool) -> Config:
        """
        Set verbose tool calls setting.

        Args:
            verbose: Whether to show MCP tool calls during chat

        Returns:
            Updated config
        """
        try:
            config = self.config_service.update_verbose_tool_calls(verbose)
            status = "enabled" if verbose else "disabled"
            self.console.print_success(f"Verbose tool calls {status}")
            return config
        except Exception as e:
            self.console.print_error(f"Failed to update verbose tool calls: {e}")
            raise

    def interactive_setup(self) -> Config:
        """
        Interactive setup wizard with MCP integration.

        Prompts for:
        1. HoneyDB API credentials (required for MCP)
        2. LLM provider API key (at least one required)
        3. UI preferences

        If configuration already exists, current values are used as defaults.

        Returns:
            Configured Config object
        """
        # Load existing config or create new one
        config_exists = self.config_service.config_exists()
        if config_exists:
            config = self.config_service.load_config()
            setup_title = "Configuration Setup"
            welcome_msg = (
                "Welcome to HoneyDB MCP CLI!\n\n"
                "This tool connects your LLM (OpenAI, Anthropic, or Gemini) with HoneyDB's\n"
                "threat intelligence tools via the Model Context Protocol (MCP).\n\n"
                "Current values are shown as defaults. Press Enter to keep existing values."
            )
        else:
            config = Config()
            setup_title = "First-Time Setup"
            welcome_msg = (
                "Welcome to HoneyDB MCP CLI!\n\n"
                "This tool connects your LLM (OpenAI, Anthropic, or Gemini) with HoneyDB's\n"
                "threat intelligence tools via the Model Context Protocol (MCP).\n\n"
                "Let's set up your configuration."
            )

        self.console.print_panel(
            welcome_msg,
            title=setup_title,
            style="info"
        )

        # Step 1: HoneyDB API Credentials (REQUIRED)
        self.console.print_panel(
            "HoneyDB API credentials are required for MCP tool access.\n"
            "Get your credentials at: https://honeydb.io/",
            title="Step 1: HoneyDB Credentials",
            style="info"
        )

        honeydb_api_id = self.console.prompt(
            "\nEnter your HoneyDB API ID",
            default=config.honeydb_api_id or ""
        )
        honeydb_api_key = self.console.prompt(
            "Enter your HoneyDB API Key",
            default=config.honeydb_api_key or ""
        )

        if not honeydb_api_id or not honeydb_api_id.strip():
            self.console.print_warning("Warning: HoneyDB API ID is required for MCP tools to work")
        else:
            config.honeydb_api_id = honeydb_api_id.strip()

        if not honeydb_api_key or not honeydb_api_key.strip():
            self.console.print_warning("Warning: HoneyDB API Key is required for MCP tools to work")
        else:
            config.honeydb_api_key = honeydb_api_key.strip()

        # Step 2: LLM Provider (at least one required)
        self.console.print_panel(
            "Choose your LLM provider (OpenAI is default).\n"
            "The LLM will use HoneyDB MCP tools during conversations.",
            title="Step 2: LLM Provider",
            style="info"
        )

        # Determine default choice based on current provider
        provider_to_choice = {
            "openai": "1",
            "anthropic": "2",
            "gemini": "3",
        }
        default_choice = provider_to_choice.get(config.default_provider, "1")

        self.console.print("\nWhich LLM provider would you like to use?")
        self.console.print("1. OpenAI (GPT-4, GPT-3.5) - Recommended")
        self.console.print("2. Anthropic (Claude)")
        self.console.print("3. Google Gemini")

        provider_choice = self.console.prompt("Enter choice (1-3)", default=default_choice)

        provider_map = {
            "1": "openai",
            "2": "anthropic",
            "3": "gemini",
        }
        provider = provider_map.get(provider_choice, "openai")
        config.default_provider = provider  # type: ignore

        # Ask for API key
        self.console.print(f"\nGet your {provider.upper()} API key:")
        if provider == "openai":
            self.console.print("  https://platform.openai.com/api-keys")
            current_key = config.openai_api_key
        elif provider == "anthropic":
            self.console.print("  https://console.anthropic.com/")
            current_key = config.anthropic_api_key
        elif provider == "gemini":
            self.console.print("  https://makersuite.google.com/app/apikey")
            current_key = config.gemini_api_key

        api_key = self.console.prompt(
            f"\nEnter your {provider} API key",
            default=current_key or ""
        )

        if api_key and api_key.strip():
            if provider == "openai":
                config.openai_api_key = api_key.strip()
            elif provider == "anthropic":
                config.anthropic_api_key = api_key.strip()
            elif provider == "gemini":
                config.gemini_api_key = api_key.strip()
        else:
            self.console.print_warning(f"Warning: {provider} API key is required for LLM access")

        # Step 3: MCP Server URL (use default production)
        # Determine default based on current URL
        is_dev = "dev" in config.mcp_server_url if config.mcp_server_url else False
        use_dev_default = "y" if is_dev else "n"

        use_dev = self.console.prompt(
            "\nUse development MCP server? (y/N)",
            default=use_dev_default
        ).lower().startswith("y")

        if use_dev:
            config.mcp_server_url = "https://honeydb-mcp-dev-db384193f137.herokuapp.com/sse/"
            self.console.print("Using development MCP server", style="dim")
        else:
            config.mcp_server_url = "https://honeydb.ai/sse/"

        # Step 4: UI Preferences
        self.console.print_panel(
            "Configure UI preferences",
            title="Step 3: UI Settings",
            style="info"
        )

        # Determine default theme choice
        theme_to_choice = {
            "auto": "1",
            "dark": "2",
            "light": "3",
        }
        default_theme_choice = theme_to_choice.get(config.theme, "1")

        self.console.print("\nChoose a theme:")
        self.console.print("1. Auto-detect (recommended)")
        self.console.print("2. Dark")
        self.console.print("3. Light")

        theme_choice = self.console.prompt("Enter choice (1-3)", default=default_theme_choice)

        theme_map = {
            "1": "auto",
            "2": "dark",
            "3": "light",
        }
        config.theme = theme_map.get(theme_choice, "auto")  # type: ignore

        # Ask about verbose tool calls
        verbose_default = "y" if config.verbose_tool_calls else "n"
        verbose = self.console.prompt(
            "\nShow MCP tool calls during chat? (y/N)",
            default=verbose_default
        ).lower().startswith("y")
        config.verbose_tool_calls = verbose

        # Save configuration
        try:
            self.config_service.save_config(config)
            self.console.print_success("\n✅ Configuration saved!")

            # Show summary
            self.console.print("\nConfiguration Summary:", style="info")
            self.console.print(f"  HoneyDB API ID: {'✅ Set' if config.honeydb_api_id else '❌ Not set'}")
            self.console.print(f"  HoneyDB API Key: {'✅ Set' if config.honeydb_api_key else '❌ Not set'}")
            self.console.print(f"  LLM Provider: {config.default_provider}")
            self.console.print(f"  MCP Server: {'Development' if 'dev' in config.mcp_server_url else 'Production'}")
            self.console.print(f"  Verbose Tool Calls: {'Yes' if config.verbose_tool_calls else 'No'}")

            if not config.honeydb_api_id or not config.honeydb_api_key:
                self.console.print_warning(
                    "\n⚠️  Warning: HoneyDB credentials not configured.\n"
                    "   MCP tools will not work until you add them.\n"
                    "   Run: honeydb-ai config set honeydb_api_id <id>\n"
                    "        honeydb-ai config set honeydb_api_key <key>"
                )

            return config
        except Exception as e:
            self.console.print_error(f"Failed to save configuration: {e}")
            raise
