import json
import logging
import os
from datetime import datetime
from typing import Optional
import sys


class DeconstructionLogger:
    """解构系统专用日志器"""

    _instance: Optional['DeconstructionLogger'] = None

    def __new__(cls):
        if cls._instance is None:
            cls._instance = super().__new__(cls)
            cls._instance._initialized = False
        return cls._instance

    def __init__(self):
        if self._initialized:
            return

        # 创建日志目录
        log_dir = os.path.join(os.getcwd(), "logs")
        os.makedirs(log_dir, exist_ok=True)

        # 创建日志文件名
        timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
        log_file = os.path.join(log_dir, f"deconstruction_system_{timestamp}.log")

        # 配置日志格式
        formatter = logging.Formatter(
            '%(asctime)s - %(name)s - %(levelname)s - [%(filename)s:%(lineno)d] - %(message)s',
            datefmt='%Y-%m-%d %H:%M:%S'
        )

        # 创建文件处理器
        file_handler = logging.FileHandler(log_file, encoding='utf-8')
        file_handler.setFormatter(formatter)
        file_handler.setLevel(logging.DEBUG)

        # 创建控制台处理器
        console_handler = logging.StreamHandler(sys.stdout)
        console_handler.setFormatter(formatter)
        console_handler.setLevel(logging.INFO)

        # 配置根日志器
        self.logger = logging.getLogger('DeconstructionSystem')
        self.logger.setLevel(logging.INFO)
        self.logger.addHandler(file_handler)
        self.logger.addHandler(console_handler)

        # 避免重复日志
        self.logger.propagate = False

        self._initialized = True
        self.logger.info("DeconstructionLogger initialized successfully")

    def get_logger(self, name: str = None) -> logging.Logger:
        """获取指定名称的子日志器"""
        if name:
            return self.logger.getChild(name)
        return self.logger

    def info(self, message: str, component: str = None):
        """记录信息级别日志"""
        if component:
            self.get_logger(component).info(message)
        else:
            self.logger.info(message)

    def warning(self, message: str, component: str = None):
        """记录警告级别日志"""
        if component:
            self.get_logger(component).warning(message)
        else:
            self.logger.warning(message)

    def error(self, message: str, component: str = None, exc_info=False):
        """记录错误级别日志"""
        if component:
            self.get_logger(component).error(message, exc_info=exc_info)
        else:
            self.logger.error(message, exc_info=exc_info)

    def debug(self, message: str, component: str = None):
        """记录调试级别日志"""
        if component:
            self.get_logger(component).debug(message)
        else:
            self.logger.debug(message)


# 全局日志器实例
logger_instance = DeconstructionLogger()


def get_logger(component: str = None) -> logging.Logger:
    """获取日志器的便捷函数"""
    return logger_instance.get_logger(component)


def log_agent_start(agent_name: str, input_data: dict = None):
    """记录Agent开始执行"""
    message = f"Agent {agent_name} started execution"
    if input_data:
        message += f" with input keys: {list(input_data.keys())}"
    logger_instance.info(message, f"Agent.{agent_name}")
    # if input_data is dict:
    #     logger_instance.info(json.dumps(input_data, ensure_ascii=False, indent=4), f"Agent.{agent_name}")
    # else:
    #     logger_instance.info(str(input_data), f"Agent.{agent_name}")


def log_agent_finish(agent_name: str, output_data: dict = None):
    """记录Agent完成执行"""
    message = f"Agent {agent_name} finished execution"
    if output_data:
        message += f" with output keys: {list(output_data.keys())}"
    logger_instance.info(message, f"Agent.{agent_name}")
    logger_instance.info(json.dumps(output_data, ensure_ascii=False, indent=4), f"Agent.{agent_name}")


def log_tool_call(tool_name: str, parameters: dict = None):
    """记录工具调用"""
    message = f"Tool {tool_name} called"
    if parameters:
        message += f" with parameters: {list(parameters.keys())}"
    logger_instance.info(message, f"Tool.{tool_name}")


def log_validation_result(validation_type: str, passed: bool, details: str = None):
    """记录验证结果"""
    status = "PASSED" if passed else "FAILED"
    message = f"Validation {validation_type} {status}"
    if details:
        message += f": {details}"

    if passed:
        logger_instance.info(message, "Validation")
    else:
        logger_instance.warning(message, "Validation")


def log_error_with_context(error: Exception, context: str, component: str = None):
    """记录带上下文的错误"""
    message = f"Error in {context}: {str(error)}"
    logger_instance.error(message, component, exc_info=True)
