import logging
import uuid
import json
from datetime import datetime

from fastapi import Request, FastAPI
from starlette.responses import JSONResponse
from starlette.requests import HTTPConnection
from typing import Callable, Awaitable

from .context import g


def add_request_routes(app: FastAPI):
    @app.middleware("http")
    async def before_request(request: Request, call_next: Callable[[Request], Awaitable[JSONResponse]]):

        # 先从header中获取x-request-id，如果没有则生成新的
        trace_id = request.headers.get('X-Request-ID') 
        if not trace_id:
            trace_id = "agent_" + str(uuid.uuid4())
        
        # user_id = "未知的 user_id"

        g.trace_id = trace_id
        # g.user_id = user_id
        response = await call_next(request)

        response.headers['X-Request-ID'] = g.trace_id
        return response


class Formatter(logging.Formatter):
    def formatTime(self, record, datefmt=None):
        # 将时间戳转换为datetime对象
        dt = datetime.fromtimestamp(record.created)
        # 格式化时间戳到毫秒
        if datefmt:
            s = dt.strftime(datefmt)
            # 去除微秒的后三位，保留毫秒部分
            s = s[:-3]
        else:
            # 去除微秒的后三位，保留毫秒部分
            s = dt.strftime("%H:%M:%S.%f")[:-3]
        return s

    def format(self, record):
        # 处理 trace_id - 在没有请求上下文时使用默认值
        if not hasattr(record, "trace_id"):
            try:
                record.trace_id = getattr(g, "trace_id")
            except LookupError:
                record.trace_id = "N/A"
        # 处理 user_id
        # if not hasattr(record, "user_id"):
        #     record.user_id = getattr(g, "user_id")

        # 格式化时间戳
        record.timestamp = self.formatTime(record, self.datefmt)

        return super().format(record)


# 这里注册session 上下文追踪一次就可以了
def init_logger_once(name,level):
    logger = logging.getLogger(name)
    logger.setLevel(level=level)
    formatter = Formatter("%(timestamp)s | %(levelname)-5s | %(trace_id)s | %(name)s:%(funcName)s:%(lineno)s - %(message)s", datefmt='%Y-%m-%d %H:%M:%S.%f')
    handler = logging.StreamHandler()
    handler.setFormatter(formatter)
    logger.addHandler(handler)


def init_with_fastapi(app,level=logging.INFO):
    init_logger_once("app",level)
    add_request_routes(app)

def info(message, *args, **kwargs):
    app_logger = logging.getLogger('app')
    app_logger.info(message, *args, **kwargs)

def debug(message, *args, **kwargs):
    app_logger = logging.getLogger('app')
    app_logger.debug(message, *args, **kwargs)

def warning(message, *args, **kwargs):
    app_logger = logging.getLogger('app')
    app_logger.warning(message, *args, **kwargs)

def error(message, *args, **kwargs):
    app_logger = logging.getLogger('app')
    app_logger.error(message, *args, **kwargs)

def critical(message, *args, **kwargs):
    app_logger = logging.getLogger('app')
    app_logger.critical(message, *args, **kwargs)
