"""
响应格式化中间件

自动为所有 BaseResponse 响应添加元数据 (request_id, timestamp)
"""
import json
import logging
from datetime import datetime
from fastapi import Request
from starlette.middleware.base import BaseHTTPMiddleware
from starlette.responses import Response, JSONResponse

logger = logging.getLogger(__name__)


class ResponseFormatterMiddleware(BaseHTTPMiddleware):
    """响应格式化中间件
    
    功能：
    1. 自动为 JSON 响应添加 metadata 字段
    2. 注入 request_id 和 timestamp
    3. 确保响应格式符合 BaseResponse 标准
    """
    
    async def dispatch(self, request: Request, call_next):
        # 处理请求
        response: Response = await call_next(request)
        
        # 只处理 JSON 响应
        content_type = response.headers.get("content-type", "")
        if "application/json" not in content_type:
            return response
        
        # 跳过某些特殊端点
        skip_paths = ["/health", "/metrics", "/docs", "/openapi.json", "/redoc"]
        if any(request.url.path.startswith(path) for path in skip_paths):
            return response
        
        try:
            # 读取响应体
            body = b""
            async for chunk in response.body_iterator:
                body += chunk
            
            # 解析 JSON
            if not body:
                return response
            
            data = json.loads(body.decode())
            
            # 检查是否已经是 BaseResponse 格式
            if isinstance(data, dict) and "code" in data and "message" in data:
                # 确保有 metadata 字段
                if "metadata" not in data or data["metadata"] is None:
                    data["metadata"] = {}
                
                # 添加 timestamp
                if "timestamp" not in data["metadata"]:
                    data["metadata"]["timestamp"] = datetime.now().isoformat()
                
                # 添加 request_id
                if hasattr(request.state, "request_id"):
                    if "request_id" not in data["metadata"]:
                        data["metadata"]["request_id"] = request.state.request_id
                
                # 创建新的响应 - 排除 content-length 让框架重新计算
                new_headers = {
                    k: v for k, v in response.headers.items() 
                    if k.lower() not in ("content-length", "content-encoding")
                }
                return JSONResponse(
                    content=data,
                    status_code=response.status_code,
                    headers=new_headers
                )
            
            # 如果不是 BaseResponse 格式,不做修改
            new_headers = {
                k: v for k, v in response.headers.items() 
                if k.lower() not in ("content-length", "content-encoding")
            }
            return Response(
                content=body,
                status_code=response.status_code,
                headers=new_headers,
                media_type=response.media_type
            )
            
        except Exception as e:
            # 如果处理失败,返回原始响应
            logger.warning(f"Failed to format response: {e}")
            return response


def setup_response_formatter(app):
    """注册响应格式化中间件"""
    app.add_middleware(ResponseFormatterMiddleware)
