"""
TransPyC 彩色日志系统
支持终端颜色输出和日志文件转储
"""
from __future__ import annotations

import sys
import os
from datetime import datetime
from typing import Any, Callable, Optional
from lib.constants.config import mode as _ConfigMode

# ANSI 颜色代码
class Colors:
    RESET = '\033[0m'
    BOLD = '\033[1m'
    DIM = '\033[2m'
    UNDERLINE = '\033[4m'
    
    # 前景色
    BLACK = '\033[30m'
    RED = '\033[31m'
    GREEN = '\033[32m'
    YELLOW = '\033[33m'
    BLUE = '\033[34m'
    MAGENTA = '\033[35m'
    CYAN = '\033[36m'
    WHITE = '\033[37m'
    
    # 高亮前景色
    BRIGHT_RED = '\033[91m'
    BRIGHT_GREEN = '\033[92m'
    BRIGHT_YELLOW = '\033[93m'
    BRIGHT_BLUE = '\033[94m'
    BRIGHT_MAGENTA = '\033[95m'
    BRIGHT_CYAN = '\033[96m'
    
    # 背景色
    BG_RED = '\033[41m'
    BG_GREEN = '\033[42m'
    BG_YELLOW = '\033[43m'
    BG_BLUE = '\033[44m'
    BG_MAGENTA = '\033[45m'
    BG_CYAN = '\033[46m'
    
    # 渐变颜色（用于详细日志）
    GRAY = '\033[90m'

# 检查是否支持颜色
def supports_color() -> bool:
    if not hasattr(sys.stdout, 'isatty'):
        return False
    if not sys.stdout.isatty():
        return False
    if os.environ.get('NO_COLOR'):
        return False
    if os.environ.get('FORCE_COLOR'):
        return True
    return True

# 全局颜色支持标志
USE_COLORS = supports_color()

# 日志级别
class LogLevel:
    DEBUG = 0
    INFO = 1
    WARNING = 2
    ERROR = 3
    CRITICAL = 4

class Logger:
    def __init__(self, name: str = "TransPyC", log_file: Optional[str] = None,
                 level: int = LogLevel.INFO, use_colors: bool = True):
        self.name = name
        self.level = level
        self.use_colors = use_colors and USE_COLORS
        self.log_file = log_file
        self.file_handler = None
        
        if log_file:
            os.makedirs(os.path.dirname(os.path.abspath(log_file)), exist_ok=True)
            self.file_handler = open(log_file, 'w', encoding='utf-8')
        
        # 进度跟踪
        self.current_phase = ""
        self.total_items = 0
        self.current_item = 0
    
    def _colorize(self, text: str, color: str) -> str:
        if self.use_colors:
            return f"{color}{text}{Colors.RESET}"
        return text
    
    def _format_time(self) -> str:
        return datetime.now().strftime("%H:%M:%S")
    
    def _write(self, message: str, level: str = ""):
        # 输出到控制台
        print(message, file=sys.stdout)
        sys.stdout.flush()
        
        # 输出到文件
        if self.file_handler:
            # 文件输出不带颜色
            clean_msg = message
            for color in vars(Colors).values():
                if isinstance(color, str) and color.startswith('\033'):
                    clean_msg = clean_msg.replace(color, '')
            timestamp = self._format_time()
            self.file_handler.write(f"[{timestamp}] {level} {clean_msg}\n")
            self.file_handler.flush()
    
    def set_phase(self, phase: str, total: int = 0) -> None:
        self.current_phase = phase
        self.total_items = total
        self.current_item = 0
        self.progress(phase, 0, total)
    
    def progress(self, message: str = "", current: int = 0, total: int = 0) -> None:
        if total > 0:
            self.total_items = total
        if current > 0:
            self.current_item = current
        
        if self.total_items > 0:
            percent: float = (self.current_item / self.total_items) * 100
            bar_length: int = 30
            filled: int = int(bar_length * self.current_item / self.total_items)
            bar: str = '█' * filled + '░' * (bar_length - filled)
            status: str = f"[{self._colorize(bar, Colors.BLUE)}] {self.current_item}/{self.total_items} ({percent:.1f}%)"
        else:
            status = ""
        
        msg: str = f"{self._colorize('▶', Colors.BRIGHT_CYAN)} {self.current_phase}"
        if status:
            msg += f" {status}"
        if message:
            msg += f" - {message}"
        
        # 使用 \r 实现进度更新
        sys.stdout.write('\r' + msg)
        sys.stdout.flush()
    
    def debug(self, message: str, category: str = "") -> None:
        if self.level > LogLevel.DEBUG:
            return
        
        prefix: str = self._colorize("DEBUG", Colors.GRAY)
        if category:
            prefix += f"[{self._colorize(category, Colors.CYAN)}]"
        
        msg: str = f"{self._colorize('├', Colors.GRAY)} {prefix}: {message}"
        self._write(msg, "DEBUG")
    
    def info(self, message: str, category: str = "") -> None:
        prefix: str = self._colorize("INFO", Colors.GREEN)
        if category:
            prefix += f"[{self._colorize(category, Colors.CYAN)}]"
        
        msg: str = f"{self._colorize('├', Colors.GREEN)} {prefix}: {message}"
        self._write(msg, "INFO")
    
    def warning(self, message: str, category: str = "", exc_info: Exception | None = None) -> None:
        prefix: str = self._colorize("WARN", Colors.BRIGHT_YELLOW)
        if category:
            prefix += f"[{self._colorize(category, Colors.CYAN)}]"

        msg: str = f"{self._colorize('├', Colors.YELLOW)} {prefix}: {message}"
        self._write(msg, "WARNING")
    
    def error(self, message: str, category: str = "", exception: Optional[Exception] = None) -> None:
        prefix: str = self._colorize("ERROR", Colors.BRIGHT_RED)
        if category:
            prefix += f"[{self._colorize(category, Colors.CYAN)}]"
        
        msg: str = f"{self._colorize('├', Colors.RED)} {prefix}: {message}"
        if exception:
            msg += f"\n{self._colorize('│', Colors.RED)} Exception: {type(exception).__name__}: {exception}"
        self._write(msg, "ERROR")
    
    def critical(self, message: str, category: str = "") -> None:
        prefix: str = self._colorize("CRITICAL", Colors.BG_RED + Colors.WHITE + Colors.BOLD)
        if category:
            prefix += f"[{self._colorize(category, Colors.CYAN)}]"
        
        msg: str = f"{self._colorize('╠', Colors.RED)} {prefix}: {message}"
        self._write(msg, "CRITICAL")
    
    def success(self, message: str, category: str = "") -> None:
        prefix: str = self._colorize("SUCCESS", Colors.BRIGHT_GREEN)
        if category:
            prefix += f"[{self._colorize(category, Colors.CYAN)}]"

        msg: str = f"{self._colorize('├', Colors.GREEN)} {prefix}: {message}"
        self._write(msg, "SUCCESS")

    def banner(self, message: str, category: str = "") -> None:
        """输出醒目的横幅标题"""
        header: str = self._colorize(message, Colors.BRIGHT_BLUE + Colors.BOLD)
        line: str = self._colorize('═' * 60, Colors.BLUE)
        msg: str = f"\n{self._colorize('╔', Colors.BLUE)}{line}{self._colorize('╗', Colors.BLUE)}\n"
        msg += f"{self._colorize('║', Colors.BLUE)} {header}\n"
        msg += f"{self._colorize('╚', Colors.BLUE)}{line}{self._colorize('╝', Colors.BLUE)}"
        self._write(msg, "BANNER")
    
    def compile_error(self, message: str, file: str = "", line: int = 0, code: str = "") -> None:
        """编译错误格式化输出"""
        header: str = self._colorize("编译错误", Colors.BG_RED + Colors.WHITE + Colors.BOLD)
        
        msg: str = f"\n{self._colorize('╔', Colors.RED)}{header}{self._colorize('╗', Colors.RED)}\n"
        
        if file and line > 0:
            location: str = f"{self._colorize(file, Colors.CYAN)}:{self._colorize(str(line), Colors.YELLOW)}"
            msg += f"{self._colorize('║', Colors.RED)} 位置：{location}\n"
        
        if code:
            msg += f"{self._colorize('║', Colors.RED)} 代码：{self._colorize(code, Colors.WHITE)}\n"
        
        msg += f"{self._colorize('║', Colors.RED)} 错误：{self._colorize(message, Colors.BRIGHT_RED)}\n"
        msg += f"{self._colorize('╚', Colors.RED)}{self._colorize('═' * 50, Colors.RED)}{self._colorize('╝', Colors.RED)}"
        
        self._write(msg, "ERROR")
    
    def compile_warning(self, message: str, file: str = "", line: int = 0, code: str = "") -> None:
        """编译警告格式化输出"""
        header: str = self._colorize("警告", Colors.BG_YELLOW + Colors.BLACK)
        
        msg: str = f"\n{self._colorize('╔', Colors.YELLOW)}{header}{self._colorize('╗', Colors.YELLOW)}\n"
        
        if file and line > 0:
            location: str = f"{self._colorize(file, Colors.CYAN)}:{self._colorize(str(line), Colors.YELLOW)}"
            msg += f"{self._colorize('║', Colors.YELLOW)} 位置：{location}\n"
        
        if code:
            msg += f"{self._colorize('║', Colors.YELLOW)} 代码：{self._colorize(code, Colors.WHITE)}\n"
        
        msg += f"{self._colorize('║', Colors.YELLOW)} 警告：{self._colorize(message, Colors.BRIGHT_YELLOW)}\n"
        msg += f"{self._colorize('╚', Colors.YELLOW)}{self._colorize('═' * 50, Colors.YELLOW)}{self._colorize('╝', Colors.YELLOW)}"
        
        self._write(msg, "WARNING")
    
    def summary(self, stats: dict[str, int | str]) -> None:
        """输出编译摘要"""
        header: str = self._colorize("编译摘要", Colors.BG_BLUE + Colors.WHITE + Colors.BOLD)
        
        msg: str = f"\n{self._colorize('╔', Colors.BLUE)}{header}{self._colorize('╗', Colors.BLUE)}\n"
        
        for key, value in stats.items():
            color: str = Colors.GREEN if value > 0 else Colors.WHITE
            msg += f"{self._colorize('║', Colors.BLUE)} {key}: {self._colorize(str(value), color)}\n"
        
        msg += f"{self._colorize('╚', Colors.BLUE)}{self._colorize('═' * 50, Colors.BLUE)}{self._colorize('╝', Colors.BLUE)}"
        
        self._write(msg, "SUMMARY")
    
    def close(self) -> None:
        if self.file_handler:
            self.file_handler.close()
            self.info(f"日志已保存到：{self.log_file}")

# 全局日志实例
_global_logger: Optional[Logger] = None

def get_logger(name: str = "TransPyC", log_file: Optional[str] = None, 
               level: int = LogLevel.INFO, use_colors: bool = True) -> Logger:
    global _global_logger
    if _global_logger is None:
        _global_logger = Logger(name, log_file, level, use_colors)
    return _global_logger

def set_logger(logger: Logger) -> None:
    global _global_logger
    _global_logger = logger

# 便捷函数
def debug(msg: str, category: str = "") -> None:
    get_logger().debug(msg, category)

def info(msg: str, category: str = "") -> None:
    get_logger().info(msg, category)

def warning(msg: str, category: str = "") -> None:
    get_logger().warning(msg, category)

def error(msg: str, category: str = "", exception: Exception | None = None) -> None:
    get_logger().error(msg, category, exception)

def success(msg: str, category: str = "") -> None:
    get_logger().success(msg, category)


def safe_call(func: Callable[..., Any], *args: Any, context: str = "", **kwargs: Any) -> Any:
    """安全调用函数，在异常时根据模式处理。

    - strict 模式：重新抛出异常
    - relaxed 模式：打印彩色警告日志并返回 None

    Args:
        func: 要调用的可调用对象
        *args, **kwargs: 传给 func 的参数
        context: 描述性上下文（用于日志消息）

    Returns:
        func 的返回值，或 None（异常时）
    """
    try:
        return func(*args, **kwargs)
    except Exception as e:
        msg = f"{context}: {type(e).__name__}: {e}" if context else f"{type(e).__name__}: {e}"
        if _ConfigMode == "strict":
            raise
        get_logger().warning(msg, "Exception")
        return None
