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 organization.models  # noqa: F401
import user_management.models  # noqa: F401
import job_configuration.models  # noqa: F401
import job_management.models  # noqa: F401
import time_tracking.models  # noqa: F401
import checklist.models  # noqa: F401
import reporting.models  # noqa: F401

Base.metadata.create_all(bind=engine)

from organization.router import router as organization_router
from user_management.router import router as user_management_router
from job_configuration.router import router as job_configuration_router
from job_management.router import router as job_management_router
from time_tracking.router import router as time_tracking_router
from checklist.router import router as checklist_router
from reporting.router import router as reporting_router

app = FastAPI(
    title="Job Management System",
    description="A comprehensive task and workflow management application for creating, assigning, tracking, and completing jobs across teams and departments.",
    version="1.0.0"
)

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


@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(organization_router)
app.include_router(user_management_router)
app.include_router(job_configuration_router)
app.include_router(job_management_router)
app.include_router(time_tracking_router)
app.include_router(checklist_router)
app.include_router(reporting_router)