"""Core widget modal definitions for interactive status widgets.

This module provides modal configuration dictionaries for core widgets
that support interactive modal activation (git-branch, profile, tmux).

Modal Definition Format:
    {
        "title": str,           # Modal title displayed in header
        "options": [            # List of modal options
            {
                "label": str,       # Display text for the option
                "action": str,      # Action identifier for routing
                "confirm": bool,    # Optional: Show confirmation prompt
                "message": str,     # Optional: Confirmation message
                "input": str,       # Optional: Input field name
                "input_label": str, # Optional: Input field label
            }
        ]
    }

The modal configuration is returned by widget activation handlers and
processed by the WidgetInteractionHandler to display the modal UI.

Reference: docs/specs/interactive-status-widgets-spec.md (lines 237-266)
"""

import asyncio
import logging
from typing import Any, Dict, List, Optional

logger = logging.getLogger(__name__)


# =============================================================================
# GIT BRANCH MODAL
# =============================================================================

async def git_branch_modal(widget_id: str, context: Any) -> Dict[str, Any]:
    """Generate modal configuration for git branch widget.

    Provides options for:
    - View Status: Show full git status output
    - Switch Branch: Checkout existing branch (with input)
    - Create Branch: Create new branch from current (with input)
    - Pull Latest: Pull from remote (with confirmation)
    - Push Changes: Push to remote (with confirmation)

    Args:
        widget_id: ID of the activated widget (e.g., "git-branch")
        context: WidgetContext with app services (profile_manager, config, etc.)

    Returns:
        Modal configuration dict with title and options array

    Example:
        >>> result = await git_branch_modal("git-branch", context)
        >>> print(result["title"])
        'Git Branch Actions'
    """
    logger.debug(f"Generating git branch modal for widget: {widget_id}")

    modal_config = {
        "title": "Git Branch Actions",
        "options": [
            {
                "label": "View Status",
                "action": "git_status",
                "description": "Show full git status output",
            },
            {
                "label": "Switch Branch",
                "action": "git_checkout",
                "description": "Switch to existing branch",
                "input": "branch_name",
                "input_label": "Branch name:",
                "placeholder": "main, feature/xyz, etc.",
            },
            {
                "label": "Create Branch",
                "action": "git_branch_new",
                "description": "Create new branch from current",
                "input": "new_branch_name",
                "input_label": "New branch name:",
                "placeholder": "feature/my-feature",
            },
            {
                "label": "Pull Latest",
                "action": "git_pull",
                "description": "Pull changes from remote",
                "confirm": True,
                "message": "Pull from remote?",
            },
            {
                "label": "Push Changes",
                "action": "git_push",
                "description": "Push commits to remote",
                "confirm": True,
                "message": "Push to remote?",
            },
        ],
        "footer": "enter to select • esc to close",
    }

    logger.debug(f"Git branch modal config: {len(modal_config['options'])} options")
    return modal_config


# =============================================================================
# PROFILE SWITCHER MODAL
# =============================================================================

async def profile_switcher_modal(widget_id: str, context: Any) -> Dict[str, Any]:
    """Generate modal configuration for LLM profile switcher widget.

    Provides options for:
    - List available profiles and set active
    - Create new profile from template

    The modal dynamically populates profile list from the profile manager.

    Args:
        widget_id: ID of the activated widget (e.g., "llm-profile")
        context: WidgetContext with profile_manager service

    Returns:
        Modal configuration dict with title and dynamic profile options

    Example:
        >>> result = await profile_switcher_modal("llm-profile", context)
        >>> # Returns modal with available profiles from profile_manager
    """
    logger.debug(f"Generating profile switcher modal for widget: {widget_id}")

    # Get profile manager from context
    profile_manager = getattr(context, "profile_manager", None) if context else None

    options = []

    if profile_manager:
        try:
            # List all available profiles
            profiles = profile_manager.list_profiles()
            current_profile = profile_manager.get_current_profile_name()

            logger.debug(f"Found {len(profiles)} profiles, current: {current_profile}")

            # Add each profile as an option
            for profile_name in profiles:
                is_current = profile_name == current_profile
                options.append({
                    "label": f"{profile_name} {'(current)' if is_current else ''}",
                    "action": "set_profile",
                    "description": profile_manager.get_profile_description(profile_name)
                                  if hasattr(profile_manager, 'get_profile_description')
                                  else f"Switch to {profile_name}",
                    "profile_name": profile_name,
                })
        except Exception as e:
            logger.error(f"Error listing profiles: {e}")
            options.append({
                "label": "Error loading profiles",
                "action": "none",
                "description": str(e),
            })
    else:
        logger.warning("No profile_manager available in context")
        options.append({
            "label": "No profiles available",
            "action": "none",
            "description": "Profile manager not found",
        })

    # Add "Create New Profile" option at the end
    options.append({
        "label": "Create New Profile",
        "action": "create_profile",
        "description": "Create a new LLM API profile",
        "input": "new_profile_name",
        "input_label": "New profile name:",
        "placeholder": "my-custom-profile",
    })

    modal_config = {
        "title": "LLM Profile Switcher",
        "options": options,
        "footer": "enter to select • esc to close",
    }

    logger.debug(f"Profile switcher modal config: {len(options)} options")
    return modal_config


# =============================================================================
# TMUX SESSION MODAL
# =============================================================================

async def tmux_session_modal(widget_id: str, context: Any) -> Dict[str, Any]:
    """Generate modal configuration for tmux session widget.

    Provides options for:
    - List available tmux sessions
    - Attach to existing session
    - Kill session
    - Create new session

    The modal dynamically populates session list from tmux.

    Args:
        widget_id: ID of the activated widget (e.g., "tmux-sessions")
        context: WidgetContext with app services

    Returns:
        Modal configuration dict with title and dynamic session options

    Example:
        >>> result = await tmux_session_modal("tmux-sessions", context)
        >>> # Returns modal with available tmux sessions
    """
    logger.debug(f"Generating tmux session modal for widget: {widget_id}")

    options = []

    try:
        # Import subprocess for tmux commands
        import subprocess

        # List tmux sessions
        result = subprocess.run(
            ["tmux", "list-sessions", "-F", "#{session_name}:#{session_attached}"],
            capture_output=True,
            text=True,
            timeout=2,
        )

        if result.returncode == 0 and result.stdout.strip():
            sessions = result.stdout.strip().split('\n')
            logger.debug(f"Found {len(sessions)} tmux sessions")

            for session_line in sessions:
                if ':' in session_line:
                    session_name, attached = session_line.split(':', 1)
                    is_attached = attached == "1"

                    options.append({
                        "label": f"{session_name} {'(attached)' if is_attached else ''}",
                        "action": "tmux_attach",
                        "description": "Attach to this session",
                        "session_name": session_name,
                    })
                    options.append({
                        "label": f"Kill {session_name}",
                        "action": "tmux_kill",
                        "description": f"Terminate session '{session_name}'",
                        "session_name": session_name,
                        "confirm": True,
                        "message": f"Kill session '{session_name}'?",
                    })
        else:
            logger.debug("No tmux sessions found or tmux not running")
            options.append({
                "label": "No active sessions",
                "action": "none",
                "description": "Create a new session to get started",
            })

    except FileNotFoundError:
        logger.debug("tmux command not found")
        options.append({
            "label": "Tmux not installed",
            "action": "none",
            "description": "Install tmux to manage sessions",
        })
    except subprocess.TimeoutExpired:
        logger.warning("tmux list-sessions timed out")
        options.append({
            "label": "Error listing sessions",
            "action": "none",
            "description": "Command timed out",
        })
    except Exception as e:
        logger.error(f"Error listing tmux sessions: {e}")
        options.append({
            "label": "Error listing sessions",
            "action": "none",
            "description": str(e),
        })

    # Add "Create New Session" option
    options.append({
        "label": "Create New Session",
        "action": "tmux_new",
        "description": "Create new tmux session",
        "input": "new_session_name",
        "input_label": "Session name:",
        "placeholder": "my-session",
    })

    modal_config = {
        "title": "Tmux Sessions",
        "options": options,
        "footer": "enter to select • esc to close",
    }

    logger.debug(f"Tmux session modal config: {len(options)} options")
    return modal_config


# =============================================================================
# MODAL REGISTRY - defined at end of file after all functions
# =============================================================================

# Note: CORE_WIDGET_MODALS dict is defined at the bottom of this file
# after all modal functions are declared to avoid NameError


def get_modal_for_widget(widget_id: str) -> Optional[callable]:
    """Get modal generator function for a widget ID.

    Args:
        widget_id: ID of the widget (e.g., "git-branch", "llm-profile")

    Returns:
        Modal generator async function or None if not found

    Example:
        >>> modal_fn = get_modal_for_widget("git-branch")
        >>> if modal_fn:
        ...     config = await modal_fn("git-branch", context)
    """
    return CORE_WIDGET_MODALS.get(widget_id)


def list_available_modals() -> List[str]:
    """List all widget IDs that have modal definitions.

    Returns:
        List of widget ID strings

    Example:
        >>> list_available_modals()
        ['git-branch', 'llm-profile', 'profile', 'tmux-sessions', 'tmux']
    """
    return list(CORE_WIDGET_MODALS.keys())


# =============================================================================
# WIDGET ACTIVATION HANDLERS
# =============================================================================

async def activate_git_branch_modal(widget_id: str, context: Any) -> Dict[str, Any]:
    """Activation handler for git-branch widget.

    This function is registered as the on_activate handler for the
    git-branch widget in the status widget registry.

    Args:
        widget_id: Widget identifier (should be "git-branch")
        context: WidgetContext with app services

    Returns:
        Modal configuration dict
    """
    return await git_branch_modal(widget_id, context)


async def activate_profile_modal(widget_id: str, context: Any) -> Dict[str, Any]:
    """Activation handler for LLM profile widget.

    This function is registered as the on_activate handler for the
    llm-profile widget in the status widget registry.

    Args:
        widget_id: Widget identifier (should be "llm-profile" or "profile")
        context: WidgetContext with app services

    Returns:
        Modal configuration dict
    """
    return await profile_switcher_modal(widget_id, context)


async def activate_tmux_modal(widget_id: str, context: Any) -> Dict[str, Any]:
    """Activation handler for tmux session widget.

    This function is registered as the on_activate handler for the
    tmux-sessions widget in the status widget registry.

    Args:
        widget_id: Widget identifier (should be "tmux-sessions" or "tmux")
        context: WidgetContext with app services

    Returns:
        Modal configuration dict
    """
    return await tmux_session_modal(widget_id, context)


# =============================================================================
# CWD DIRECTORY MODAL
# =============================================================================

async def cwd_directory_modal(widget_id: str, context: Any) -> Dict[str, Any]:
    """Generate modal configuration for current working directory widget.

    Provides options for:
    - Show Current Path: Display full current working directory path
    - Go to Parent: Navigate up one directory level
    - Go to Home: Navigate to user's home directory
    - Enter Custom Path: Navigate to arbitrary path

    Args:
        widget_id: ID of the activated widget (e.g., "cwd")
        context: WidgetContext with app services

    Returns:
        Modal configuration dict with title and options array
    """
    from pathlib import Path

    logger.debug(f"Generating cwd directory modal for widget: {widget_id}")

    # Get current directory info
    try:
        cwd = Path.cwd()
        home = Path.home()

        # Format current path for display
        if cwd == home:
            current_display = "~ (home)"
        elif cwd.is_relative_to(home):
            rel_path = cwd.relative_to(home)
            current_display = f"~/{rel_path}"
        else:
            current_display = str(cwd)

        # Check if we're at root or home to disable parent option
        can_go_parent = cwd != cwd.parent and cwd != home
    except Exception as e:
        logger.error(f"Error getting current directory: {e}")
        current_display = "Unknown directory"
        can_go_parent = False

    modal_config = {
        "title": "Directory Navigator",
        "options": [
            {
                "label": f"Current: {current_display}",
                "action": "cwd_show",
                "description": str(cwd) if 'cwd' in locals() else "Current directory",
            },
            {
                "label": "Go to Parent",
                "action": "cwd_parent",
                "description": "Navigate up one level",
                "disabled": not can_go_parent,
            },
            {
                "label": "Go to Home",
                "action": "cwd_home",
                "description": f"Navigate to {home}",
            },
            {
                "label": "Enter Custom Path",
                "action": "cwd_custom",
                "description": "Navigate to arbitrary path",
                "input": "custom_path",
                "input_label": "Path:",
                "placeholder": "/path/to/dir or ~/relative/path",
            },
        ],
        "footer": "enter to select • esc to close",
    }

    logger.debug(f"CWD directory modal config: {len(modal_config['options'])} options")
    return modal_config


async def activate_cwd_modal(widget_id: str, context: Any) -> Dict[str, Any]:
    """Activation handler for current working directory widget.

    This function is registered as the on_activate handler for the
    cwd widget in the status widget registry.

    Args:
        widget_id: Widget identifier (should be "cwd")
        context: WidgetContext with app services

    Returns:
        Modal configuration dict
    """
    return await cwd_directory_modal(widget_id, context)


# =============================================================================
# MODAL REGISTRY (defined after all functions to avoid NameError)
# =============================================================================

# Mapping of widget IDs to their modal generator functions
CORE_WIDGET_MODALS: Dict[str, callable] = {
    "git-branch": git_branch_modal,
    "llm-profile": profile_switcher_modal,
    "profile": profile_switcher_modal,  # Alias
    "tmux-sessions": tmux_session_modal,
    "tmux": tmux_session_modal,  # Alias
    "cwd": cwd_directory_modal,
}
