from contextlib import asynccontextmanager

from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from fastapi.staticfiles import StaticFiles

from src.apis.base import api_router
from src.apis.version1.healthcheck import health_router
from src.apis.version1.admin.login import login_router
from src.core.config import settings
from src.core.log_conf import logger
from src.core.middleware import RequestLoggingMiddleware
from src.db.models.base import Base
from src.db.session import engine
from src.db.utils import check_db_connected, check_db_disconnected
from src.webapps.base import api_router as web_app_router


@asynccontextmanager
async def lifespan(app: FastAPI):
    await check_db_connected()
    yield
    await check_db_disconnected()


def include_router(app: FastAPI):
    app.include_router(api_router, tags=["api"])
    app.include_router(web_app_router, tags=["webapp"])
    app.include_router(health_router, tags=["admin"])
    app.include_router(login_router, tags=["webapp"])


def configure_static(app: FastAPI):
    app.mount("/static", StaticFiles(directory="src/static"), name="static")


def add_middle_ware(app: FastAPI):
    app.add_middleware(
        CORSMiddleware,
        allow_origins=["*"],
        allow_credentials=True,
        allow_methods=["*"],
        allow_headers=["*"],
    )
    app.add_middleware(RequestLoggingMiddleware)


def create_tables():
    Base.metadata.create_all(bind=engine)


def start_application(log):
    log.info(f"using database: {settings.DATABASE_URL}")
    app = FastAPI(
        title=settings.PROJECT_NAME, version=settings.PROJECT_VERSION, lifespan=lifespan
    )
    include_router(app)
    configure_static(app)
    add_middle_ware(app)
    create_tables()
    return app


kontor = start_application(logger)
