"""
日志工具类
提供统一的日志记录接口
"""
import logging
import traceback
from functools import wraps
from flask import request, current_app, g
import json


class Logger:
    """日志工具类"""
    
    @staticmethod
    def get_logger(name='app'):
        """获取日志器"""
        if current_app and 'LOGGERS' in current_app.config:
            return current_app.config['LOGGERS'].get(name, current_app.logger)
        return logging.getLogger(name)
    
    @staticmethod
    def info(message, extra_data=None, logger_name='app'):
        """记录info级别日志"""
        logger = Logger.get_logger(logger_name)
        
        if extra_data:
            message = f"{message} | 额外数据: {json.dumps(extra_data, ensure_ascii=False)}"
        
        logger.info(message)
    
    @staticmethod
    def error(message, exception=None, extra_data=None, logger_name='app'):
        """记录error级别日志"""
        logger = Logger.get_logger(logger_name)
        
        full_message = message
        
        if exception:
            full_message += f" | 异常: {str(exception)}"
            full_message += f" | 堆栈跟踪: {traceback.format_exc()}"
        
        if extra_data:
            full_message += f" | 额外数据: {json.dumps(extra_data, ensure_ascii=False)}"
        
        logger.error(full_message)
    
    @staticmethod
    def warning(message, extra_data=None, logger_name='app'):
        """记录warning级别日志"""
        logger = Logger.get_logger(logger_name)
        
        if extra_data:
            message = f"{message} | 额外数据: {json.dumps(extra_data, ensure_ascii=False)}"
        
        logger.warning(message)
    
    @staticmethod
    def debug(message, extra_data=None, logger_name='app'):
        """记录debug级别日志"""
        logger = Logger.get_logger(logger_name)
        
        if extra_data:
            message = f"{message} | 额外数据: {json.dumps(extra_data, ensure_ascii=False)}"
        
        logger.debug(message)
    
    @staticmethod
    def global_error(message, exception=None, extra_data=None):
        """记录全局错误日志"""
        Logger.error(message, exception, extra_data, 'global_error')
    
    @staticmethod
    def access_log(message, extra_data=None):
        """记录访问日志"""
        logger = Logger.get_logger('access')
        
        # 添加请求信息
        request_info = {
            'method': request.method if request else None,
            'url': request.url if request else None,
            'remote_addr': request.remote_addr if request else None,
            'user_agent': request.headers.get('User-Agent') if request else None,
        }
        
        if extra_data:
            request_info.update(extra_data)
        
        full_message = f"{message} | 请求信息: {json.dumps(request_info, ensure_ascii=False)}"
        logger.info(full_message)


def log_request_info(f):
    """装饰器：记录请求信息"""
    @wraps(f)
    def decorated_function(*args, **kwargs):
        if request:
            Logger.access_log(
                f"API请求: {request.method} {request.path}",
                {
                    'args': dict(request.args),
                    'json': request.get_json() if request.is_json else None,
                    'form': dict(request.form) if request.form else None
                }
            )
        
        try:
            result = f(*args, **kwargs)
            if request:
                Logger.access_log(f"API响应成功: {request.method} {request.path}")
            return result
        except Exception as e:
            if request:
                Logger.access_log(
                    f"API响应错误: {request.method} {request.path}",
                    {'error': str(e)}
                )
            raise
    
    return decorated_function


def log_function_call(func_name=None):
    """装饰器：记录函数调用"""
    def decorator(f):
        @wraps(f)
        def decorated_function(*args, **kwargs):
            name = func_name or f.__name__
            Logger.info(f"函数调用开始: {name}")
            
            try:
                result = f(*args, **kwargs)
                Logger.info(f"函数调用成功: {name}")
                return result
            except Exception as e:
                Logger.error(f"函数调用失败: {name}", e)
                raise
        
        return decorated_function
    return decorator


class ErrorHandler:
    """全局错误处理器"""
    
    @staticmethod
    def handle_exception(exception, context=None):
        """处理异常并记录日志"""
        error_data = {
            'exception_type': type(exception).__name__,
            'context': context or '未知上下文'
        }
        
        # 记录到全局错误日志
        Logger.global_error(
            f"全局异常捕获: {str(exception)}",
            exception,
            error_data
        )
        
        # 记录到应用日志
        Logger.error(
            f"应用异常: {str(exception)}",
            exception,
            error_data
        )
    
    @staticmethod
    def handle_database_error(exception, operation=None):
        """处理数据库错误"""
        error_data = {
            'operation': operation or '未知数据库操作',
            'error_type': 'database_error'
        }
        
        Logger.global_error(
            f"数据库操作失败: {operation or '未知操作'}",
            exception,
            error_data
        )
    
    @staticmethod
    def handle_api_error(exception, endpoint=None, request_data=None):
        """处理API错误"""
        error_data = {
            'endpoint': endpoint or '未知端点',
            'request_data': request_data,
            'error_type': 'api_error'
        }
        
        Logger.global_error(
            f"API错误: {endpoint or '未知端点'}",
            exception,
            error_data
        )
