import logging
from collections.abc import AsyncIterator
from contextlib import asynccontextmanager
from typing import Any

from fastapi import FastAPI, Request
from fastapi.exceptions import RequestValidationError
# 1. IMPORT THE CORS MIDDLEWARE HERE
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import JSONResponse
from starlette.exceptions import HTTPException as StarletteHTTPException

from app.config import get_settings
from app.database import Database
from app.errors import ApiError
from app.middleware.logging import JsonRequestLoggingMiddleware
from app.middleware.rate_limit import RateLimitMiddleware
from app.routes import auth, cameras, clips, events, health
from app.schemas.common import ErrorResponse

settings = get_settings()


@asynccontextmanager
async def lifespan(app: FastAPI) -> AsyncIterator[None]:
    database = Database(settings)
    await database.connect()
    app.state.database = database
    try:
        yield
    finally:
        await database.close()


def configure_logging() -> None:
    logging.basicConfig(level=settings.log_level, format="%(message)s")


def create_app() -> FastAPI:
    configure_logging()
    app = FastAPI(
        title=settings.app_name,
        version="1.0.0",
        description="Frontend-facing API gateway for AI-powered NVR metadata, playback, and camera management.",
        lifespan=lifespan,
        responses={401: {"model": ErrorResponse}, 404: {"model": ErrorResponse}, 429: {"model": ErrorResponse}},
    )
    app.add_exception_handler(ApiError, api_error_handler)
    app.add_exception_handler(StarletteHTTPException, http_error_handler)
    app.add_exception_handler(RequestValidationError, validation_error_handler)

    # Custom existing middlewares
    app.add_middleware(JsonRequestLoggingMiddleware)
    app.add_middleware(RateLimitMiddleware, settings=settings)

    # 2. ADD CORS MIDDLEWARE HERE (At the bottom of the middleware chain)
    # This ensures it executes FIRST on incoming requests, intercepting the OPTIONS preflight.
    app.add_middleware(
        CORSMiddleware,
        allow_origins=["http://192.168.1.140:3000"], # Your frontend URL from the headers
        allow_credentials=True,
        allow_methods=["*"], # Allows POST, GET, OPTIONS, etc.
        allow_headers=["*"], # Allows content-type, authorization, etc.
    )

    app.include_router(health.router)
    app.include_router(auth.router)
    app.include_router(cameras.router)
    app.include_router(clips.router)
    app.include_router(events.router)
    return app


async def api_error_handler(request: Request, exc: ApiError) -> JSONResponse:
    content = exc.detail if isinstance(exc.detail, dict) else {"error": "api_error", "message": str(exc.detail)}
    return JSONResponse(status_code=exc.status_code, content=content, headers=getattr(exc, "headers", None))


async def http_error_handler(request: Request, exc: StarletteHTTPException) -> JSONResponse:
    detail = exc.detail if isinstance(exc.detail, str) else "Request failed"
    error = "not_found" if exc.status_code == 404 else "http_error"
    return JSONResponse(status_code=exc.status_code, content={"error": error, "message": detail})


async def validation_error_handler(request: Request, exc: RequestValidationError) -> JSONResponse:
    errors: list[dict[str, Any]] = exc.errors()
    return JSONResponse(
        status_code=422,
        content={"error": "validation_error", "message": "Request validation failed", "details": errors},
    )


app = create_app()
