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 sip_calculation.models  # noqa: F401

Base.metadata.create_all(bind=engine)

from sip_calculation.router import router as sip_calculation_router

app = FastAPI(
    title="SIP Calculator",
    description="A single-page financial planning tool that calculates and visualizes potential returns from systematic investment plans in mutual funds.",
    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(sip_calculation_router)