"""
Permission UI Dialog

Interactive permission prompts with Rich UI.
"""

import json
from pathlib import Path
from typing import Literal, Optional

from rich.console import Console
from rich.panel import Panel
from rich.prompt import Prompt
from rich.syntax import Syntax
from rich.table import Table

PermissionChoice = Literal["allow", "always", "deny"]


class PermissionDialog:
    """
    Interactive permission dialog with Rich UI.

    Provides:
    - Formatted tool information display
    - User choice: Allow once, Always allow, Deny
    - Keyboard shortcuts: 1/y, 2/a, 3/n
    - Config updates for "Always allow"
    """

    def __init__(self, console: Optional[Console] = None):
        """
        Initialize permission dialog.

        Args:
            console: Rich Console instance (creates default if None)
        """
        self.console = console or Console()

    def ask_permission(
        self,
        tool_name: str,
        description: str,
        **kwargs
    ) -> PermissionChoice:
        """
        Ask user for permission to execute tool.

        Args:
            tool_name: Name of tool being executed
            description: Human-readable description of action
            **kwargs: Tool arguments to display

        Returns:
            "allow" (once), "always" (always allow), or "deny"

        Examples:
            >>> dialog = PermissionDialog()
            >>> choice = dialog.ask_permission(
            ...     "write",
            ...     "Create new file",
            ...     path="config.json",
            ...     content="..."
            ... )
        """
        # Build display content
        self._display_permission_request(tool_name, description, kwargs)

        # Get user choice
        choice = self._get_user_choice()

        return choice

    def _display_permission_request(
        self,
        tool_name: str,
        description: str,
        kwargs: dict
    ) -> None:
        """
        Display permission request with Rich formatting.

        Args:
            tool_name: Tool name
            description: Action description
            kwargs: Tool arguments
        """
        self.console.print()  # Blank line for spacing

        # Create panel content
        content_lines = []

        # Tool info
        content_lines.append(f"[bold cyan]Tool:[/bold cyan] {tool_name}")
        content_lines.append(f"[bold cyan]Action:[/bold cyan] {description}")

        # Arguments (if any)
        if kwargs:
            content_lines.append("")
            content_lines.append("[bold cyan]Arguments:[/bold cyan]")

            # Create table for arguments
            arg_table = Table(show_header=False, box=None, padding=(0, 2))
            arg_table.add_column("Key", style="yellow")
            arg_table.add_column("Value", style="white")

            for key, value in kwargs.items():
                # Truncate long values
                value_str = str(value)
                if len(value_str) > 100:
                    value_str = value_str[:97] + "..."

                arg_table.add_row(key, value_str)

            # Render table to string
            from io import StringIO
            string_io = StringIO()
            temp_console = Console(file=string_io, force_terminal=True)
            temp_console.print(arg_table)
            content_lines.append(string_io.getvalue().rstrip())

        content = "\n".join(content_lines)

        # Display panel
        panel = Panel(
            content,
            title="[bold red]⚠ Permission Required[/bold red]",
            border_style="red",
            padding=(1, 2),
        )

        self.console.print(panel)

    def _get_user_choice(self) -> PermissionChoice:
        """
        Get user permission choice with keyboard shortcuts.

        Returns:
            "allow", "always", or "deny"
        """
        self.console.print()
        self.console.print("[bold]Options:[/bold]")
        self.console.print("  [green]1[/green] or [green]y[/green] - Allow once")
        self.console.print("  [cyan]2[/cyan] or [cyan]a[/cyan] - Always allow")
        self.console.print("  [red]3[/red] or [red]n[/red] - Deny")
        self.console.print()

        # Get choice with validation
        valid_choices = ["1", "2", "3", "y", "a", "n"]
        choice = Prompt.ask(
            "Choose",
            choices=valid_choices,
            default="1",
        )

        # Map to permission choice
        choice_map = {
            "1": "allow",
            "y": "allow",
            "2": "always",
            "a": "always",
            "3": "deny",
            "n": "deny",
        }

        return choice_map[choice]  # type: ignore


def update_config_for_always_allow(
    project_path: Path,
    tool_name: str,
    agent_name: Optional[str] = None,
) -> None:
    """
    Update groknroll.json to always allow a tool.

    Args:
        project_path: Path to project root
        tool_name: Tool to always allow
        agent_name: Agent name (for agent-specific permissions)

    Examples:
        >>> update_config_for_always_allow(
        ...     Path("/project"),
        ...     "write",
        ...     agent_name="code-agent"
        ... )
    """
    config_path = project_path / "groknroll.json"

    # Load existing config or create new
    if config_path.exists():
        try:
            with open(config_path) as f:
                config = json.load(f)
        except (json.JSONDecodeError, IOError):
            config = {}
    else:
        config = {}

    # Update permissions
    if agent_name:
        # Agent-specific permission
        if "agent" not in config:
            config["agent"] = {}
        if agent_name not in config["agent"]:
            config["agent"][agent_name] = {}
        if "permission" not in config["agent"][agent_name]:
            config["agent"][agent_name]["permission"] = {}

        config["agent"][agent_name]["permission"][tool_name] = "allow"
    else:
        # Global permission
        if "permission" not in config:
            config["permission"] = {}

        config["permission"][tool_name] = "allow"

    # Write config back
    with open(config_path, "w") as f:
        json.dump(config, f, indent=2)


# Convenience function for quick permission checks
def ask_permission(
    tool_name: str,
    description: str,
    project_path: Optional[Path] = None,
    agent_name: Optional[str] = None,
    **kwargs
) -> PermissionChoice:
    """
    Convenience function to ask for permission.

    Args:
        tool_name: Name of tool
        description: Action description
        project_path: Project path (for "always allow" config updates)
        agent_name: Agent name (for agent-specific permissions)
        **kwargs: Tool arguments

    Returns:
        "allow", "always", or "deny"

    Examples:
        >>> choice = ask_permission(
        ...     "write",
        ...     "Create config file",
        ...     path="config.json"
        ... )
    """
    dialog = PermissionDialog()
    choice = dialog.ask_permission(tool_name, description, **kwargs)

    # Update config if "always allow"
    if choice == "always" and project_path:
        update_config_for_always_allow(project_path, tool_name, agent_name)

    return choice
