"""기본 콘솔 출력 및 로깅을 위한 모듈."""

import sys
from collections.abc import Generator
from contextlib import contextmanager
from typing import Any

from rich.console import Console
from rich.status import Status

from selvage.src.utils.logging import get_logger


class BaseConsole:
    """기본 콘솔 출력 및 로깅을 관리하는 클래스."""

    def __init__(self) -> None:
        """콘솔 인스턴스를 초기화합니다."""
        # MCP 모드에 따른 조건부 출력 스트림 설정
        if self._is_mcp_mode():
            # MCP 모드: 모든 출력을 stderr로 (프로토콜 안전성)
            self.console = Console(file=sys.stderr)
        else:
            # 일반 모드: stdout 사용 (파이프라인 호환성)
            self.console = Console()

        self.logger = get_logger(__name__)

    def _is_mcp_mode(self) -> bool:
        """MCP 모드 여부를 확인합니다."""
        try:
            from selvage.src.config import is_mcp_mode

            return is_mcp_mode()
        except (ImportError, AttributeError, Exception):
            return False

    def success(self, message: str) -> None:
        """성공 메시지를 출력합니다."""
        self.console.print(message, style="bold green")
        self.logger.info(f"SUCCESS: {message}")

    def info(self, message: str) -> None:
        """정보 메시지를 출력합니다."""
        self.console.print(message, style="bold blue")
        self.logger.info(f"INFO: {message}")

    def log_info(self, message: str) -> None:
        """정보 메시지를 로그 파일에만 기록합니다 (터미널 출력 없음)."""
        self.logger.info(f"INFO: {message}")

    def warning(self, message: str) -> None:
        """경고 메시지를 출력합니다."""
        self.console.print(message, style="bold yellow")
        self.logger.warning(f"WARNING: {message}")

    def error(self, message: str, exception: Exception | None = None) -> None:
        """오류 메시지를 출력합니다.

        Args:
            message: 오류 메시지
            exception: 예외 객체 (있을 경우 상세한 로그 정보를 저장)
        """
        self.console.print(message, style="bold red")
        if exception:
            self.logger.error(f"ERROR: {message}", exc_info=True)
        else:
            self.logger.error(f"ERROR: {message}")

    def print(self, *args: Any, **kwargs: Any) -> None:  # noqa: ANN401
        """Rich 콘솔의 print 메서드를 래핑합니다."""
        self.console.print(*args, **kwargs)

    @contextmanager
    def status(self, message: str) -> Generator[Status, None, None]:
        """진행 상황을 스피너와 함께 표시합니다."""
        with self.console.status(message, spinner="dots") as status:
            yield status

    def is_debug_mode(self) -> bool:
        """디버그 모드 여부 확인"""
        try:
            from selvage.src.config import get_default_debug_mode

            return get_default_debug_mode()
        except (ImportError, Exception):
            return False


# 전역 콘솔 인스턴스 (lazy 초기화)
# MCP 모드가 설정된 후 생성되도록 함수로 접근
_console_instance: BaseConsole | None = None


def get_console() -> BaseConsole:
    """전역 콘솔 인스턴스를 반환합니다 (lazy 초기화)."""
    global _console_instance
    if _console_instance is None:
        _console_instance = BaseConsole()
    return _console_instance


def reset_console() -> None:
    """전역 콘솔 인스턴스를 재설정합니다.

    MCP 모드 변경 후 호출하여 새 설정을 반영합니다.
    """
    global _console_instance
    _console_instance = None


# 하위 호환성을 위한 프록시 객체
class _ConsoleProxy:
    """BaseConsole 메서드를 전역 인스턴스로 위임하는 프록시."""

    def __getattr__(self, name: str) -> Any:  # noqa: ANN401
        return getattr(get_console(), name)


console = _ConsoleProxy()
