import time
from typing import Any, Callable

from fastapi import FastAPI, Request
from setech.utils import get_logger
from starlette import status
from starlette.middleware.cors import CORSMiddleware
from starlette.responses import RedirectResponse, Response
from tortoise.contrib.fastapi import register_tortoise

from service.api.routes import api_router
from service.config import TORTOISE_ORM, settings
from service.utils.web import do_init

do_init()
logger = get_logger("api")

app = FastAPI(
    debug=settings.debug,
    root_path=settings.root_path,
    title=settings.project_name,
    version="0.1.0",
    servers=[
        {"url": "http://localhost:8000/", "description": "Local"},
        {"url": "https://test.{{ cookiecutter.project_slug }}.com/", "description": "Staging environment"},
        {"url": "https://{{ cookiecutter.project_slug }}.com/", "description": "Production environment"},
    ],
)


@app.middleware("http")
async def add_process_time_header(request: Request, call_next: Callable[[Any], Any]) -> Response:
    start_time = time.time()
    if settings.debug:
        logger.info(
            f"Received request for '{request.url}'",
            extra={
                "headers": request.headers,
                "content": await request.body(),
                "cookies": request.cookies,
                "url": request.url,
            },
        )
    response: Response = await call_next(request)
    process_time = time.time() - start_time
    response.headers["X-Process-Time"] = str(process_time)
    return response


app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],  # [str(origin).strip("/") for origin in settings.cors_origins],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)
app.include_router(api_router)


@app.get("/", tags=["Root redirect"])
def root_view() -> RedirectResponse:
    return RedirectResponse("/docs", status_code=status.HTTP_308_PERMANENT_REDIRECT)


register_tortoise(
    app,
    config=TORTOISE_ORM,
    add_exception_handlers=True,
)
