import json
import logging
import time
import uuid
import os
from datetime import datetime

from fastapi import Request, Response
from starlette.middleware.base import BaseHTTPMiddleware, RequestResponseEndpoint

from app.services.log_config import LOG_R_Q_DIR, LOG_FILENAME_FORMAT, LOG_DATE_FORMAT, encrypt_data

logger = logging.getLogger("videogen")

os.makedirs(LOG_R_Q_DIR, exist_ok=True)


def get_today_log_file() -> str:
    today = datetime.now().strftime(LOG_DATE_FORMAT)
    filename = LOG_FILENAME_FORMAT.format(date=today)
    return os.path.join(LOG_R_Q_DIR, filename)


class RequestLoggingMiddleware(BaseHTTPMiddleware):
    async def dispatch(
        self, request: Request, call_next: RequestResponseEndpoint
    ) -> Response:
        path = request.url.path
        
        if path.startswith("/static/") or path.startswith("/videos/") or path.startswith("/images/"):
            return await call_next(request)
        
        if path in ("/internal/health", "/internal/api-docs", "/openapi.json", "/internal/api-redoc","internal/decrypt-data"):
            return await call_next(request)
        #GET请求不记录日志
        if request.method == "GET":
            return await call_next(request)
        request_id = str(uuid.uuid4())[:8]
        start = time.perf_counter()

        request_body = {}
        try:
            if request.method in ("POST", "PUT", "PATCH"):
                body = await request.json()
                request_body = body
        except Exception:
            pass

        response = await call_next(request)

        duration_ms = round((time.perf_counter() - start) * 1000, 1)

        log_entry = {
            "timestamp": datetime.now().isoformat(),
            "request_id": request_id,
            "method": request.method,
            "path": request.url.path,
            "query_params": dict(request.query_params),
            "request_body": encrypt_data(request_body) if request_body else "",
            "status": response.status_code,
            "duration_ms": duration_ms,
            "ip": request.client.host if request.client else "-",
            "user_agent": request.headers.get("user-agent", "-"),
        }

        log_file = get_today_log_file()
        with open(log_file, "a", encoding="utf-8") as f:
            f.write(json.dumps(log_entry, ensure_ascii=False) + "\n")

        response.headers["X-Request-ID"] = request_id
        return response
