from fastapi import FastAPI, Request, HTTPException
from fastapi.responses import JSONResponse
import logging

from starlette.middleware.cors import CORSMiddleware

from app.infrastructure.database.database import init_db
from app.infrastructure.fastapi.accessory_routes import router as accessory_router
from app.infrastructure.fastapi.city_routes import router as city_router
from app.infrastructure.fastapi.delivery_accessory_routes import router as delivery_accessory_router
from app.infrastructure.fastapi.delivery_order_routes import router as delivery_order_router
from app.infrastructure.fastapi.federal_district_routes import router as federal_district_router
from app.infrastructure.fastapi.role_routes import router as role_router
from app.infrastructure.fastapi.status_routes import router as status_router
from app.infrastructure.fastapi.total_order_routes import router as total_order_router
from app.infrastructure.fastapi.truck_routes import router as truck_router
from app.infrastructure.fastapi.user_routes import router as user_router

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

app = FastAPI()

app.add_middleware(
    CORSMiddleware,
    allow_origins=['*'],
    allow_credentials=True,
    allow_methods=['GET', 'POST', 'PUT', 'DELETE'],
    allow_headers=['*'],
)

init_db()

app.include_router(accessory_router, prefix='/api', tags=['accessories'])
app.include_router(city_router, prefix='/api', tags=['cities'])
app.include_router(delivery_accessory_router, prefix='/api', tags=['delivery accessories'])
app.include_router(delivery_order_router, prefix='/api', tags=['delivery orders'])
app.include_router(federal_district_router, prefix='/api', tags=['federal districts'])
app.include_router(role_router, prefix='/api', tags=['roles'])
app.include_router(status_router, prefix='/api', tags=['statuses'])
app.include_router(total_order_router, prefix='/api', tags=['total orders'])
app.include_router(truck_router, prefix='/api', tags=['trucks'])
app.include_router(user_router, prefix='/api', tags=['users'])


@app.middleware('http')
async def log_requests(request: Request, call_next):
    logger.info(f'Request: {request.method} {request.url}')
    response = await call_next(request)
    logger.info(f'Response: {response.status_code}')
    return response


@app.exception_handler(HTTPException)
async def http_exception_handler(request: Request, exc: HTTPException):
    return JSONResponse(
        status_code=exc.status_code,
        content={'detail': exc.detail},
    )


@app.exception_handler(Exception)
async def generic_exception_handler(request: Request, exc: Exception):
    logger.error(f'An error occurred: {exc}')
    return JSONResponse(
        status_code=500,
        content={'detail': 'An internal error occurred. Please try again later.'},
    )
