from datetime import datetime

from fastapi import FastAPI, Request
from fastapi.encoders import jsonable_encoder
from fastapi.exceptions import RequestValidationError
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import JSONResponse, ORJSONResponse
from sqlalchemy.exc import IntegrityError, SQLAlchemyError
from starlette.middleware.gzip import GZipMiddleware

from app.config import settings
from app.core.exceptions import AppException
from app.core.i18n.middleware import LanguageMiddleware
from app.db.init_db import init_db
from app.middleware.network_traffic import setup_network_traffic_monitoring
from app.middleware.rate_limit import setup_rate_limiting
from app.services.access.rbac_bootstrap_service import RBACBootstrapService
from common_logging import LoggingMiddleware, get_logger, setup_logging
from common_metrics import setup_metrics

setup_logging()
logger = get_logger(__name__)
app = FastAPI(
    title="Base Platform API",
    version="2.0.0",
    description="Multi-tenant AI Platform with RAG and Agent capabilities",
    default_response_class=ORJSONResponse if settings.USE_ORJSON else JSONResponse,
)
setup_rate_limiting(app)
setup_network_traffic_monitoring(app, enabled=settings.TRAFFIC_MONITORING_ENABLED)
app.add_middleware(LoggingMiddleware)
setup_metrics(app, "base-platform")
if settings.ENVIRONMENT == "production":
    from app.core.security_utils import CSRFMiddleware

    app.add_middleware(CSRFMiddleware)
app.add_middleware(LanguageMiddleware, default_locale="zh_CN")
from app.core.tenant_context import TenantContextMiddleware

app.add_middleware(TenantContextMiddleware)
from app.middleware.service_guard import ServiceGuardMiddleware

app.add_middleware(ServiceGuardMiddleware)
if settings.GZIP_COMPRESSION_ENABLED:
    app.add_middleware(GZipMiddleware, minimum_size=settings.GZIP_MINIMUM_SIZE)
logger.info(f"CORS Origins: {settings.CORS_ORIGINS}")
app.add_middleware(
    CORSMiddleware,
    allow_origins=settings.CORS_ORIGINS,
    allow_credentials=True,
    allow_methods=settings.CORS_METHODS,
    allow_headers=settings.CORS_HEADERS,
)


@app.exception_handler(AppException)
async def app_exception_handler(request: Request, exc: AppException):
    request_id = getattr(request.state, "request_id", None)
    logger.error(f"[{request_id}] {exc.code}: {exc.message} - {request.method} {request.url}")
    return JSONResponse(
        status_code=exc.status_code,
        content={
            "error": {"code": exc.code, "message": exc.message},
            "request_id": request_id,
            "timestamp": datetime.utcnow().isoformat(),
        },
    )


@app.exception_handler(SQLAlchemyError)
async def sqlalchemy_exception_handler(request: Request, exc: SQLAlchemyError):
    request_id = getattr(request.state, "request_id", None)
    logger.error(f"[{request_id}] Database error: {str(exc)} - {request.method} {request.url}")
    if isinstance(exc, IntegrityError):
        status_code = 409
        code = "CONSTRAINT_VIOLATION"
        message = "数据库约束冲突"
    else:
        status_code = 500
        code = "DATABASE_ERROR"
        message = "数据库操作失败"
    return JSONResponse(
        status_code=status_code,
        content={
            "error": {"code": code, "message": message},
            "request_id": request_id,
            "timestamp": datetime.utcnow().isoformat(),
        },
    )


@app.exception_handler(Exception)
async def generic_exception_handler(request: Request, exc: Exception):
    request_id = getattr(request.state, "request_id", None)
    logger.exception(
        f"[{request_id}] Unhandled exception: {str(exc)} - {request.method} {request.url}"
    )
    return JSONResponse(
        status_code=500,
        content={
            "error": {"code": "INTERNAL_SERVER_ERROR", "message": "服务器内部错误"},
            "request_id": request_id,
            "timestamp": datetime.utcnow().isoformat(),
        },
    )


@app.exception_handler(RequestValidationError)
async def validation_exception_handler(request: Request, exc: RequestValidationError):
    logger.error(f"Validation error for {request.method} {request.url}")
    logger.error(f"Validation errors: {exc.errors()}")
    from app.config import settings

    if settings.ENVIRONMENT == "production":
        return JSONResponse(status_code=422, content={"detail": "Invalid request parameters"})
    else:
        return JSONResponse(status_code=422, content={"detail": jsonable_encoder(exc.errors())})


@app.on_event("startup")
async def startup_event():
    from app.core.env_validator import print_environment_info, validate_environment

    try:
        validate_environment()
        print_environment_info()
    except Exception as e:
        logger.error(f"❌ Environment validation failed: {e}")
        raise
    init_db()
    RBACBootstrapService.bootstrap_legacy_rbac_state()
    logger.info("✅ Base Platform API started")


@app.get("/")
async def root():
    return {"message": "Base Platform API", "version": "2.0.0", "status":"running"}


@app.get("/health")
async def health_check():
    return {"status": "healthy", "message": "Base Platform API is running"}


from app.api.v1 import api_router

app.include_router(api_router, prefix=settings.API_V1_STR)
from app.api.internal.switch_mode import router as internal_switch_router

app.include_router(internal_switch_router, prefix="/internal", tags=["internal"])
if __name__ == "__main__":
    import uvicorn

    uvicorn.run(app, host="0.0.0.0", port=8000)
