"""
INDELIS API — Cemetery & Gravesite Management SaaS Platform
"""
import logging
from contextlib import asynccontextmanager

from fastapi import FastAPI, Request
from fastapi.exceptions import RequestValidationError
from fastapi.middleware.cors import CORSMiddleware
from starlette.exceptions import HTTPException

from src.database.load_models import load_all_models

load_all_models()

from src.core.config import settings
from src.core.exceptions import AppException
from src.core.handlers.errors import (
    app_exception_handler,
    http_exception_handler,
    validation_error_handler,
    general_exception_handler,
)
from src.middleware.logging import LoggingMiddleware
from src.middleware.security import SecurityHeadersMiddleware
from src.middleware.tenant import TenantMiddleware
from src.database.session import AsyncSessionLocal

logging.basicConfig(
    level=getattr(logging, settings.LOG_LEVEL, logging.INFO),
    format="%(asctime)s %(name)s %(levelname)s %(message)s",
)
logger = logging.getLogger(__name__)


@asynccontextmanager
async def lifespan(app: FastAPI):
    logger.info(f"INDELIS API starting — env={settings.ENVIRONMENT}")
    # Expose session factory on app state for middleware
    app.state.db_session = AsyncSessionLocal
    yield
    logger.info("INDELIS API shutting down")


app = FastAPI(
    title="INDELIS API",
    description="Cemetery & Gravesite Management SaaS Platform API",
    version="1.0.0",
    debug=settings.DEBUG,
    docs_url="/api/docs",
    redoc_url="/api/redoc",
    lifespan=lifespan,
)

# ── CORS ──────────────────────────────────────────────────────────────────────
app.add_middleware(
    CORSMiddleware,
    allow_origins=settings.ALLOWED_ORIGINS,
    allow_origin_regex=r"https?://.*\.indelis\.com|https?://[^/]+\.localhost(:\d+)?",
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

# ── Custom Middleware (last-added runs first) ──────────────────────────────────
app.add_middleware(TenantMiddleware)
app.add_middleware(SecurityHeadersMiddleware)
app.add_middleware(LoggingMiddleware)

# ── Exception Handlers ────────────────────────────────────────────────────────
app.add_exception_handler(AppException, app_exception_handler)
app.add_exception_handler(HTTPException, http_exception_handler)
app.add_exception_handler(RequestValidationError, validation_error_handler)
app.add_exception_handler(Exception, general_exception_handler)


# ── Health Checks ─────────────────────────────────────────────────────────────
@app.get("/health", tags=["Health"])
async def health():
    return {"status": "healthy", "service": "indelis-api", "version": "1.0.0"}


@app.get("/health/live", tags=["Health"])
async def liveness():
    return {"status": "alive"}


@app.get("/health/ready", tags=["Health"])
async def readiness():
    from src.database.session import engine
    from sqlalchemy import text
    try:
        async with engine.connect() as conn:
            await conn.execute(text("SELECT 1"))
        db_ok = True
    except Exception:
        db_ok = False

    try:
        from src.database.session import get_redis
        redis = await get_redis()
        await redis.ping()
        redis_ok = True
    except Exception:
        redis_ok = False

    ready = db_ok and redis_ok
    return {
        "status": "ready" if ready else "degraded",
        "database": "ok" if db_ok else "error",
        "redis": "ok" if redis_ok else "error",
    }


# ── Routers ───────────────────────────────────────────────────────────────────
from src.apps.auth.router import router as auth_router
from src.apps.tenants.router import router as tenants_router
from src.apps.users.router import router as users_router
from src.apps.sections.router import router as sections_router
from src.apps.plots.router import router as plots_router
from src.apps.records.router import router as records_router
from src.apps.sales.router import router as sales_router
from src.apps.billing.router import router as billing_router
from src.apps.scheduling.router import router as scheduling_router
from src.apps.memorials.router import router as memorials_router
from src.apps.news.router import router as news_router
from src.apps.reports.router import router as reports_router
from src.apps.settings.router import router as settings_router
from src.apps.public.router import router as public_router
from src.apps.site_admin.router import router as site_admin_router
from src.apps.ai.router import router as ai_router

API_V1 = "/api/v1"
app.include_router(auth_router, prefix=API_V1)
app.include_router(tenants_router, prefix=API_V1)
app.include_router(users_router, prefix=API_V1)
app.include_router(sections_router, prefix=API_V1)
app.include_router(plots_router, prefix=API_V1)
app.include_router(records_router, prefix=API_V1)
app.include_router(sales_router, prefix=API_V1)
app.include_router(billing_router, prefix=API_V1)
app.include_router(scheduling_router, prefix=API_V1)
app.include_router(memorials_router, prefix=API_V1)
app.include_router(news_router, prefix=API_V1)
app.include_router(reports_router, prefix=API_V1)
app.include_router(settings_router, prefix=API_V1)
app.include_router(ai_router, prefix=API_V1)
app.include_router(public_router, prefix="/api")
app.include_router(site_admin_router, prefix="/api")


if __name__ == "__main__":
    import uvicorn

    uvicorn.run(
        "src.main:app",
        host="0.0.0.0",
        port=8000,
        reload=settings.DEBUG,
        log_level=settings.LOG_LEVEL.lower(),
    )
