import jwt
from fastapi import FastAPI, Request
from fastapi.middleware.cors import CORSMiddleware
from fastapi.openapi.docs import get_swagger_ui_html
from fastapi.responses import JSONResponse

from app import mongo, schedules
from app.api import v1
from app.config import config
from app.utils.logger_util import logger

app = FastAPI(
    docs_url=None,
    redirect_slashes=False
)


@app.on_event("startup")
async def startup_event():
    await mongo.migrate()
    await schedules.start()
    logger.info("App started")


@app.on_event("shutdown")
async def shutdown_event():
    logger.info("App shutted down")


if config["MODE"] == 'development':
    logger.debug("Development mode")
    app.add_middleware(
        CORSMiddleware,
        allow_origins=["*"],
        allow_credentials=True,
        allow_methods=["*"],
        allow_headers=["*"],
    )


@app.middleware("http")
async def http_processing(request: Request, call_next) -> any:
    if request.method == "GET" or "/api/v1/auth/login" in str(request.url):
        return await call_next(request)

    authorization = request.headers.get("authorization")
    if not authorization or not authorization.startswith("Bearer "):
        return JSONResponse(content={"detail": "Отсутствует токен"}, status_code=401)

    bearer = authorization.replace("Bearer ", "")
    payload = jwt.decode(bearer, config["JWT_SECRET_KEY"], algorithms=[config["JWT_ALGORITHM"]])

    user = await mongo.users_collection.find_one({"id": int(payload["sub"])})
    if not user:
        return JSONResponse(content={"detail": "Пользователь не найден"}, status_code=401)

    request.state.user = user
    return await call_next(request)


@app.get("/apidoc", include_in_schema=False)
async def custom_swagger_ui_html():
    return get_swagger_ui_html(
        openapi_url=app.openapi_url,
        title=f"{app.title} - Swagger UI"
    )


app.include_router(v1.router, prefix='/api/v1')
