"""CLI context for type-safe access to global options and services.

This module provides the CLIContext dataclass that replaces the raw dict
used in ctx.obj, enabling type-safe access to global options and lazy
initialization of services like ConfigManager and OutputFormatter.
"""

from __future__ import annotations

from dataclasses import dataclass
from pathlib import Path
from typing import TYPE_CHECKING

import typer

if TYPE_CHECKING:
    from teams_phone.infrastructure import ConfigManager, OutputFormatter
    from teams_phone.infrastructure.debug_logger import DebugLogger


@dataclass
class CLIContext:
    """Type-safe context for CLI commands.

    Stores global options and provides lazy access to services.

    Attributes:
        json_output: Output in JSON format for automation.
        verbose: Enable verbose output and debug information.
        tenant: Tenant name override (None = use default from config).
        no_color: Disable colored output.
        debug_log_path: Path for debug log file (None = disabled).
        config_manager: Lazily initialized ConfigManager instance.
        output_formatter: Initialized OutputFormatter for output.
        debug_logger: Initialized DebugLogger for debug logging.
    """

    json_output: bool = False
    verbose: bool = False
    tenant: str | None = None
    no_color: bool = False
    debug_log_path: Path | None = None
    config_manager: ConfigManager | None = None
    output_formatter: OutputFormatter | None = None
    debug_logger: DebugLogger | None = None

    def get_output_formatter(self) -> OutputFormatter:
        """Get or create the OutputFormatter.

        Creates an OutputFormatter on first access using the json_output
        and no_color settings from this context.

        Returns:
            The OutputFormatter instance.
        """
        if self.output_formatter is None:
            from teams_phone.infrastructure import OutputFormatter

            self.output_formatter = OutputFormatter(
                json_mode=self.json_output,
                no_color=self.no_color,
            )
        return self.output_formatter

    def get_config_manager(self) -> ConfigManager:
        """Get or create the ConfigManager.

        Creates a ConfigManager on first access. This defers disk I/O
        until actually needed, avoiding unnecessary config file reads
        on operations like --help.

        Returns:
            The ConfigManager instance.
        """
        if self.config_manager is None:
            from teams_phone.infrastructure import ConfigManager

            self.config_manager = ConfigManager()
        return self.config_manager

    def get_debug_logger(self) -> DebugLogger | None:
        """Get the DebugLogger if debug logging is enabled.

        Returns:
            The DebugLogger instance if debug_log_path is set, None otherwise.
        """
        return self.debug_logger


def get_context(ctx: typer.Context) -> CLIContext:
    """Retrieve typed CLIContext from Typer context.

    Args:
        ctx: The Typer/Click context object.

    Returns:
        The CLIContext instance stored in ctx.obj.

    Raises:
        RuntimeError: If ctx.obj is not a CLIContext (programming error).
    """
    if not isinstance(ctx.obj, CLIContext):
        raise RuntimeError(
            "CLIContext not found in context. "
            "This is a programming error - ensure the main callback ran."
        )
    return ctx.obj
