from fastapi import FastAPI, Request, status
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import JSONResponse
from sqlalchemy.exc import IntegrityError, OperationalError, DataError
from utils.utils import Base, engine

# Import every module's models so ORM classes register with Base before create_all
import submissions.models  # noqa: F401

Base.metadata.create_all(bind=engine)

from submissions.router import router as submissions_router

app = FastAPI(title="Todo Task Submission", description="A simple form submission application that captures name and email entries and displays them in a list.", version="1.0.0")

app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_credentials=False,
    allow_methods=["*"],
    allow_headers=["*"],
)

# Global exception handlers — convert DB-layer errors into clean HTTP responses
@app.exception_handler(IntegrityError)
async def integrity_error_handler(request: Request, exc: IntegrityError):
    msg = str(exc.orig) if exc.orig else str(exc)
    lower = msg.lower()
    if "unique" in lower or "duplicate" in lower:
        return JSONResponse(status_code=status.HTTP_409_CONFLICT, content={"detail": "Resource already exists or violates unique constraint."})
    if "foreign key" in lower:
        return JSONResponse(status_code=status.HTTP_400_BAD_REQUEST, content={"detail": "Referenced resource does not exist or cannot be deleted while in use."})
    if "not null" in lower or "null value" in lower:
        return JSONResponse(status_code=status.HTTP_400_BAD_REQUEST, content={"detail": "Required field is missing."})
    if "check constraint" in lower:
        return JSONResponse(status_code=status.HTTP_400_BAD_REQUEST, content={"detail": "Value violates a database check constraint."})
    return JSONResponse(status_code=status.HTTP_400_BAD_REQUEST, content={"detail": "Database integrity error."})

@app.exception_handler(DataError)
async def data_error_handler(request: Request, exc: DataError):
    return JSONResponse(status_code=status.HTTP_400_BAD_REQUEST, content={"detail": "Invalid data format or value out of range."})

@app.exception_handler(OperationalError)
async def operational_error_handler(request: Request, exc: OperationalError):
    return JSONResponse(status_code=status.HTTP_503_SERVICE_UNAVAILABLE, content={"detail": "Database temporarily unavailable. Please retry."})

app.include_router(submissions_router)