from __future__ import annotations

import logging

from fastapi import FastAPI, Request
from fastapi.exceptions import RequestValidationError
from fastapi.responses import JSONResponse
from pydantic import ValidationError

from app.api.integrations import router as integrations_router
from app.api.licences import router as licences_router
from app.core.config import settings
from app.schemas.licensing import ErrorResponse
from app.services.errors import LicensingError

logging.basicConfig(level=settings.log_level)
logger = logging.getLogger("tribute_director_licensing")

app = FastAPI(
    title="Tribute Director Licensing API",
    version="1.0.0",
)
app.include_router(licences_router)
app.include_router(integrations_router)


@app.exception_handler(LicensingError)
async def licensing_error_handler(
    request: Request,
    exc: LicensingError,
) -> JSONResponse:
    logger.info(
        "licensing_request_denied",
        extra={
            "path": request.url.path,
            "code": exc.code,
        },
    )
    body = ErrorResponse(code=exc.code, message=exc.message)
    return JSONResponse(
        status_code=exc.http_status,
        content=body.model_dump(by_alias=True),
    )


@app.exception_handler(ValidationError)
async def validation_error_handler(
    request: Request,
    exc: ValidationError,
) -> JSONResponse:
    logger.info("malformed_request", extra={"path": request.url.path})
    body = ErrorResponse(
        code="malformedRequest",
        message="The request could not be processed.",
    )
    return JSONResponse(status_code=422, content=body.model_dump(by_alias=True))


@app.exception_handler(RequestValidationError)
async def request_validation_error_handler(
    request: Request,
    exc: RequestValidationError,
) -> JSONResponse:
    logger.info("malformed_request", extra={"path": request.url.path})
    body = ErrorResponse(
        code="malformedRequest",
        message="The request could not be processed.",
    )
    return JSONResponse(status_code=422, content=body.model_dump(by_alias=True))


@app.get("/healthz")
def healthz() -> dict[str, str]:
    return {"status": "ok"}
