"""System command handler.

Handles /help, /config, /status, /permissions, /version, /restart.
"""

import logging
import platform
from datetime import datetime
from typing import Any, Dict

from kollabor_events.models import (
    CommandCategory,
    CommandDefinition,
    CommandMode,
    CommandResult,
    SlashCommand,
    SubcommandInfo,
    UIConfig,
)

from ..base import BaseCommandHandler

logger = logging.getLogger(__name__)


class SystemCommandHandler(BaseCommandHandler):
    """Handles /help, /config, /status, /version, /permissions, /restart."""

    MODAL_ACTIONS = set()  # No modal actions for system commands

    @property
    def llm_service(self):
        """Get LLM service via service registry."""
        return self.event_bus.get_service("llm_service")

    @property
    def agent_manager(self):
        """Get agent manager via service registry."""
        return self.event_bus.get_service("agent_manager")

    @property
    def permission_manager(self):
        """Get permission manager via service registry."""
        return self.event_bus.get_service("permission_manager")

    def register_commands(self) -> None:
        """Register system commands."""
        # Register /help command
        help_command = CommandDefinition(
            name="help",
            description="Show available commands and usage",
            handler=self.handle_help,
            plugin_name="system",
            category=CommandCategory.SYSTEM,
            mode=CommandMode.INSTANT,
            aliases=["h", "?"],
            icon="?",
        )
        self.command_registry.register_command(help_command)

        # Register /config command (runs as AltView fullscreen editor)
        config_command = CommandDefinition(
            name="config",
            description="Open system configuration panel",
            handler=self.handle_config,
            plugin_name="system",
            category=CommandCategory.SYSTEM,
            mode=CommandMode.ALTVIEW,
            aliases=["settings", "preferences"],
            icon="[CFG]",
        )
        self.command_registry.register_command(config_command)

        # Register /status command
        status_command = CommandDefinition(
            name="status",
            description="Show system status and diagnostics",
            handler=self.handle_status,
            plugin_name="system",
            category=CommandCategory.SYSTEM,
            mode=CommandMode.STATUS_TAKEOVER,
            aliases=["info", "diagnostics"],
            icon="[STATS]",
            ui_config=UIConfig(
                type="table",
                navigation=["? ?", "Esc"],
                height=12,
                title="System Status",
                footer="↑↓ navigate • Esc exit",
            ),
        )
        self.command_registry.register_command(status_command)

        # Register /permissions command
        permissions_command = CommandDefinition(
            name="permissions",
            description="Manage tool execution permissions",
            handler=self.handle_permissions,
            plugin_name="system",
            category=CommandCategory.SYSTEM,
            mode=CommandMode.INLINE_INPUT,
            aliases=["perms", "security", "permission"],
            icon="[LOCK]",
            cli_hidden=False,  # Allow CLI: kollab --permissions trust
            subcommands=[
                SubcommandInfo("show", "", "Show current permission settings"),
                SubcommandInfo("default", "", "Use DEFAULT mode (HIGH risk only)"),
                SubcommandInfo(
                    "strict", "", "Use CONFIRM_ALL mode (prompt everything)"
                ),
                SubcommandInfo("trust", "", "Use TRUST_ALL mode (approve everything)"),
                SubcommandInfo("stats", "", "Show permission statistics"),
                SubcommandInfo("clear", "", "Clear session approvals"),
            ],
        )
        self.command_registry.register_command(permissions_command)

        # Register /version command
        version_command = CommandDefinition(
            name="version",
            description="Show application version information",
            handler=self.handle_version,
            plugin_name="system",
            category=CommandCategory.SYSTEM,
            mode=CommandMode.INSTANT,
            aliases=["v", "ver"],
            icon="[INFO]",
        )
        self.command_registry.register_command(version_command)

        # Register /restart command
        restart_command = CommandDefinition(
            name="restart",
            description="Clear conversation and start fresh session",
            handler=self.handle_restart,
            plugin_name="system",
            category=CommandCategory.SYSTEM,
            mode=CommandMode.INSTANT,
            aliases=["new", "clear"],
            icon="[NEW]",
        )
        self.command_registry.register_command(restart_command)

    async def handle_help(self, command: SlashCommand) -> CommandResult:
        """Handle /help command.

        Args:
            command: Parsed slash command.

        Returns:
            Command execution result.
        """
        try:
            if command.args:
                # Show help for specific command
                command_name = command.args[0]
                return await self._show_command_help(command_name)
            else:
                # Show all commands categorized by plugin
                return await self._show_all_commands()

        except Exception as e:
            self.logger.error(f"Error in help command: {e}")
            return CommandResult(
                success=False,
                message=f"Error displaying help: {str(e)}",
                display_type="error",
            )

    async def handle_config(self, command: SlashCommand) -> CommandResult:
        """Handle /config command via ConfigAltView.

        Pushes the config editor AltView onto the stack manager so it
        takes over the terminal alternate buffer with full widget support.

        Args:
            command: Parsed slash command.

        Returns:
            Command execution result.
        """
        try:
            from plugins.altview.config_altview import ConfigAltView

            altview = ConfigAltView()

            # Get or create the stack manager
            stack_mgr = self.event_bus.get_service("altview_stack_manager")
            if not stack_mgr:
                try:
                    from kollabor_tui.altview.stack_manager import (
                        AltViewStackManager,
                    )

                    renderer = self.event_bus.get_service("renderer")
                    stack_mgr = AltViewStackManager(self.event_bus, renderer)
                    self.event_bus.register_service(
                        "altview_stack_manager", stack_mgr
                    )
                except Exception as e:
                    logger.error(
                        "Failed to create AltView stack manager: %s", e
                    )
                    return CommandResult(
                        success=False,
                        message=f"Config UI unavailable: {e}",
                        display_type="error",
                    )

            # Inject config_service for reading/saving config values
            llm_svc = self.llm_service
            if llm_svc and hasattr(llm_svc, "config"):
                altview.config_service = llm_svc.config
            elif self.config_manager:
                altview.config_service = self.config_manager

            # push() blocks until the user exits
            await stack_mgr.push(altview, "config")

            return CommandResult(
                success=True,
                message="",
                display_type="success",
            )

        except Exception as e:
            self.logger.error(f"Error in config command: {e}")
            return CommandResult(
                success=False,
                message=f"Error opening configuration: {str(e)}",
                display_type="error",
            )

    async def handle_status(self, command: SlashCommand) -> CommandResult:
        """Handle /status command.

        Args:
            command: Parsed slash command.

        Returns:
            Command execution result with status modal UI.
        """
        try:
            # Create status modal definition (similar to config modal)
            status_definition = self._get_status_modal_definition()

            return CommandResult(
                success=True,
                message="System status opened",
                ui_config=UIConfig(
                    type="modal",
                    title=status_definition["title"],
                    width=status_definition.get("width"),
                    height=status_definition.get("height"),
                    modal_config=status_definition,
                ),
                display_type="modal",
            )

        except Exception as e:
            self.logger.error(f"Error in status command: {e}")
            return CommandResult(
                success=False,
                message=f"Error showing status: {str(e)}",
                display_type="error",
            )

    def _get_status_modal_definition(self) -> Dict[str, Any]:
        """Get status modal definition with live system data.

        Returns:
            Modal definition dictionary for status display.
        """
        stats = self.command_registry.get_registry_stats()

        return {
            "title": "System Status",
            "footer": "Esc to close",
            # Width and height are dynamic (terminal_width - 2, terminal_height - 4)
            "sections": [
                {
                    "title": "Commands",
                    "widgets": [
                        {
                            "type": "label",
                            "label": "Registered",
                            "value": str(stats.get("total_commands", 0)),
                        },
                        {
                            "type": "label",
                            "label": "Enabled",
                            "value": str(stats.get("enabled_commands", 0)),
                        },
                        {
                            "type": "label",
                            "label": "Categories",
                            "value": str(stats.get("categories", 0)),
                        },
                    ],
                },
                {
                    "title": "Plugins",
                    "widgets": [
                        {
                            "type": "label",
                            "label": "Active",
                            "value": str(stats.get("plugins", 0)),
                        },
                    ],
                },
                {
                    "title": "System",
                    "widgets": [
                        {
                            "type": "label",
                            "label": "Python",
                            "value": f"{platform.python_version()}",
                        },
                        {
                            "type": "label",
                            "label": "Platform",
                            "value": platform.system(),
                        },
                        {
                            "type": "label",
                            "label": "Architecture",
                            "value": platform.machine(),
                        },
                    ],
                },
                {
                    "title": "Services",
                    "widgets": [
                        {"type": "label", "label": "Event Bus", "value": "[ok] Active"},
                        {
                            "type": "label",
                            "label": "Input Handler",
                            "value": "[ok] Running",
                        },
                        {
                            "type": "label",
                            "label": "Terminal Renderer",
                            "value": "[ok] Active",
                        },
                    ],
                },
            ],
            "actions": [
                {
                    "key": "Escape",
                    "label": "Close",
                    "action": "cancel",
                    "style": "secondary",
                }
            ],
        }

    async def handle_permissions(self, command: SlashCommand) -> CommandResult:
        """Handle /permissions command.

        Args:
            command: Parsed slash command.

        Returns:
            Command execution result.
        """
        try:
            # Get permission manager via service registry
            permission_manager = self.permission_manager
            if not permission_manager:
                return CommandResult(
                    success=False,
                    message="Permission system not initialized",
                    display_type="error",
                )

            # Handle args (can be list or string)
            if isinstance(command.args, list):
                subcommand = command.args[0].lower() if command.args else "show"
            elif isinstance(command.args, str):
                subcommand = command.args.strip().lower() if command.args else "show"
            else:
                subcommand = "show"

            # Handle subcommands
            if subcommand in ("", "show"):
                # Show current settings
                mode = permission_manager.approval_mode
                stats = permission_manager.get_stats()

                mode_descriptions = {
                    "ApprovalMode.DEFAULT": "DEFAULT - Confirm HIGH risk only",
                    "ApprovalMode.CONFIRM_ALL": "CONFIRM ALL - Confirm everything",
                    "ApprovalMode.AUTO_APPROVE_EDITS": "AUTO APPROVE EDITS - Confirm shell only",
                    "ApprovalMode.TRUST_ALL": "TRUST ALL - Approve everything (DANGEROUS)",
                }
                mode_str = str(mode)
                mode_desc = mode_descriptions.get(mode_str, mode_str)

                message = f"""[info] Permission Settings

Mode: {mode_desc}

Statistics:
  Total checks: {stats['total_checks']}
  Auto-approved: {stats['auto_approved']}
  User approved: {stats['user_approved']}
  Denied: {stats['denied']}
  Blocked: {stats['blocked']}

Commands:
  /permissions default - Use DEFAULT mode
  /permissions strict - Use CONFIRM_ALL mode
  /permissions trust - Use TRUST_ALL mode
  /permissions stats - Show statistics
  /permissions project - Show project approvals
  /permissions clear - Clear session approvals
  /permissions clear-project - Clear project approvals"""

                return CommandResult(success=True, message=message, display_type="info")

            elif subcommand == "default":
                from kollabor_events.permissions_models import ApprovalMode

                permission_manager.set_approval_mode(ApprovalMode.DEFAULT)
                return CommandResult(
                    success=True,
                    message="Permission mode set to DEFAULT (confirm HIGH risk only)",
                    display_type="success",
                )

            elif subcommand in ("strict", "confirm_all"):
                from kollabor_events.permissions_models import ApprovalMode

                permission_manager.set_approval_mode(ApprovalMode.CONFIRM_ALL)
                return CommandResult(
                    success=True,
                    message="Permission mode set to CONFIRM_ALL (confirm everything)",
                    display_type="success",
                )

            elif subcommand in ("trust", "trust_all"):
                from kollabor_events.permissions_models import ApprovalMode

                permission_manager.set_approval_mode(ApprovalMode.TRUST_ALL)
                return CommandResult(
                    success=True,
                    message="Permission mode set to TRUST_ALL (approve everything - DANGEROUS)",
                    display_type="warning",
                )

            elif subcommand == "stats":
                stats = permission_manager.get_stats()
                message = f"""[info] Permission Statistics

Total checks: {stats['total_checks']}
Auto-approved: {stats['auto_approved']}
User approved: {stats['user_approved']}
Denied: {stats['denied']}
Blocked: {stats['blocked']}"""

                return CommandResult(success=True, message=message, display_type="info")

            elif subcommand == "clear":
                permission_manager.clear_session_approvals()
                return CommandResult(
                    success=True,
                    message="Session approvals cleared",
                    display_type="success",
                )

            elif subcommand == "project":
                project_approvals = permission_manager.get_project_approvals()
                if project_approvals:
                    approvals_list = "\n".join(
                        f"  - {key}" for key in project_approvals
                    )
                    message = f"[info] Project Approvals ({len(project_approvals)}):\n{approvals_list}"
                else:
                    message = "[info] No project approvals recorded"
                return CommandResult(success=True, message=message, display_type="info")

            elif subcommand in ("clear-project", "clearproject"):
                permission_manager.clear_project_approvals()
                return CommandResult(
                    success=True,
                    message="Project approvals cleared",
                    display_type="success",
                )

            else:
                return CommandResult(
                    success=False,
                    message=(
                        f"[error] Unknown subcommand: {subcommand}\n\n"
                        "Use: /permissions [show|default|strict|trust|stats|project|clear|clear-project]"
                    ),
                    display_type="error",
                )

        except Exception as e:
            self.logger.error(f"Error in permissions command: {e}")
            import traceback

            traceback.print_exc()
            return CommandResult(
                success=False,
                message=f"[error] Error managing permissions: {str(e)}",
                display_type="error",
            )

    async def handle_version(self, command: SlashCommand) -> CommandResult:
        """Handle /version command.

        Args:
            command: Parsed slash command.

        Returns:
            Command execution result.
        """
        try:
            # Get version information
            version_info = self._get_version_info()

            message = f"""Kollabor CLI v{version_info['version']}
Built: {version_info['build_date']}
Python: {version_info['python_version']}
Platform: {version_info['platform']}"""

            return CommandResult(
                success=True, message=message, display_type="info", data=version_info
            )

        except Exception as e:
            self.logger.error(f"Error in version command: {e}")
            return CommandResult(
                success=False,
                message=f"Error getting version: {str(e)}",
                display_type="error",
            )

    async def handle_restart(self, command: SlashCommand) -> CommandResult:
        """Handle /restart command - clear conversation and start fresh.

        Saves current conversation (if enabled), clears history, rebuilds
        system prompt with current agent, and starts a new session.

        Args:
            command: Parsed slash command.

        Returns:
            Command execution result.
        """
        try:
            llm_service = self.llm_service
            if not llm_service:
                return CommandResult(
                    success=False,
                    message="LLM service not available",
                    display_type="error",
                )

            # Get current state for message
            agent_manager = self.agent_manager
            agent = agent_manager.get_active_agent() if agent_manager else None
            agent_name = agent.name if agent else "default"
            old_message_count = (
                len(llm_service.conversation_history) - 1
            )  # Exclude system

            # Clear conversation manager first (saves conversation if enabled)
            if hasattr(llm_service, "conversation_manager"):
                llm_service.conversation_manager.clear_conversation()

            # Re-initialize conversation (clears history, rebuilds system prompt)
            await llm_service._initialize_conversation()

            return CommandResult(
                success=True,
                message=f"[ok] Session restarted\n  Agent: {agent_name}\n  Cleared: {old_message_count} messages",
                display_type="success",
            )

        except Exception as e:
            self.logger.error(f"Error in restart command: {e}")
            return CommandResult(
                success=False,
                message=f"Error restarting session: {str(e)}",
                display_type="error",
            )

    async def _show_command_help(self, command_name: str) -> CommandResult:
        """Show help for a specific command.

        Args:
            command_name: Name of command to show help for.

        Returns:
            Command result with help information.
        """
        command_def = self.command_registry.get_command(command_name)
        if not command_def:
            return CommandResult(
                success=False,
                message=f"Unknown command: /{command_name}",
                display_type="error",
            )

        # Format detailed help for the command
        help_text = f"""Command: /{command_def.name}
Description: {command_def.description}
Plugin: {command_def.plugin_name}
Category: {command_def.category.value}
Mode: {command_def.mode.value}"""

        if command_def.aliases:
            help_text += f"\nAliases: {', '.join(command_def.aliases)}"

        if command_def.parameters:
            help_text += "\nParameters:"
            for param in command_def.parameters:
                required = " (required)" if param.required else ""
                help_text += f"\n  {param.name}: {param.description}{required}"

        return CommandResult(success=True, message=help_text, display_type="info")

    async def _show_all_commands(self) -> CommandResult:
        """Show all available commands grouped by plugin in a status modal.

        Returns:
            Command result with status modal UI config.
        """
        # Get commands grouped by plugin
        plugin_categories = self.command_registry.get_plugin_categories()

        # Build command list for modal display
        command_sections = []

        for plugin_name in sorted(plugin_categories.keys()):
            commands = self.command_registry.get_commands_by_plugin(plugin_name)
            if not commands:
                continue

            # Create section for this plugin
            section_commands = []
            for cmd in sorted(commands, key=lambda c: c.name):
                aliases = f" ({', '.join(cmd.aliases)})" if cmd.aliases else ""
                section_commands.append(
                    {"name": f"/{cmd.name}{aliases}", "description": cmd.description}
                )

            command_sections.append(
                {
                    "title": f"{plugin_name.title()} Commands",
                    "commands": section_commands,
                }
            )

        return CommandResult(
            success=True,
            message="Help opened in status modal",
            ui_config=UIConfig(
                type="status_modal",
                title="Available Commands",
                # Width and height are dynamic (terminal_width - 2)
                modal_config={
                    "sections": command_sections,
                    "footer": "Esc/Enter close • /help <command> for details",
                    "scrollable": True,
                },
            ),
            display_type="status_modal",
        )

    def _get_version_info(self) -> Dict[str, str]:
        """Get application version information.

        Returns:
            Dictionary with version details.
        """
        import sys

        from .... import __version__

        return {
            "version": __version__,
            "build_date": datetime.now().strftime("%Y-%m-%d"),
            "python_version": f"{sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}",
            "platform": platform.system(),
            "architecture": platform.machine(),
        }
