"""نقطه ورود برنامه FastAPI برای Core Platform Service."""
from __future__ import annotations

from contextlib import asynccontextmanager

from fastapi import FastAPI, Request
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import JSONResponse

from app import __version__
from app.api.v1 import api_router, health
from app.core.cache import cache
from app.core.config import settings
from app.core.logging import configure_logging, get_logger
from app.middlewares.tenant import TenantResolutionMiddleware
from shared.exceptions import AppError
from shared.responses import ErrorDetail, ErrorResponse

configure_logging()
logger = get_logger(__name__)


@asynccontextmanager
async def lifespan(app: FastAPI):
    logger.info("service_starting", extra={"service": settings.service_name})
    # Best-effort: ensure commercial meta-registry kinds exist (idempotent).
    # Skip in unit tests — discovery_catalog / seed handle kinds there.
    if settings.environment != "test":
        try:
            from app.commercial.service import CommercialRegistryService
            from app.core.database import AsyncSessionLocal

            async with AsyncSessionLocal() as session:
                await CommercialRegistryService(session).ensure_builtin_kinds()
            logger.info("commercial_registry_kinds_ready")
        except Exception as exc:  # noqa: BLE001
            logger.warning("commercial_kinds_bootstrap_skipped", extra={"error": str(exc)})
    yield
    await cache.close()
    logger.info("service_stopped")


def create_app() -> FastAPI:
    app = FastAPI(
        title=f"{settings.platform_name} - Core Platform Service",
        version=__version__,
        description="سرویس هسته پلتفرم SaaS چندمستأجری (فاز ۱).",
        lifespan=lifespan,
    )

    # CORS - در production باید origins محدود شود.
    # allow_origin_regex برای ساب‌دامین tenantها (<slug>.torbatyar.ir)
    app.add_middleware(
        CORSMiddleware,
        allow_origins=settings.cors_origin_list,
        allow_origin_regex=r"https?://([a-z0-9-]+\.)*torbatyar\.ir",
        allow_credentials=False,
        allow_methods=["*"],
        allow_headers=["*"],
    )

    # Middleware تشخیص tenant.
    app.add_middleware(
        TenantResolutionMiddleware, base_domain=settings.platform_base_domain or None
    )

    # ثبت exception handlerها برای تبدیل خطاهای دامنه به پاسخ استاندارد.
    _register_exception_handlers(app)

    # routerها
    app.include_router(health.router)
    app.include_router(api_router, prefix=settings.api_v1_prefix)

    return app


def _register_exception_handlers(app: FastAPI) -> None:
    @app.exception_handler(AppError)
    async def app_error_handler(request: Request, exc: AppError) -> JSONResponse:
        response = ErrorResponse(
            error=ErrorDetail(
                code=exc.error_code, message=exc.message, details=exc.details
            )
        )
        return JSONResponse(status_code=exc.status_code, content=response.model_dump())

    @app.exception_handler(Exception)
    async def unhandled_handler(request: Request, exc: Exception) -> JSONResponse:
        logger.error("unhandled_exception", extra={"error": str(exc)}, exc_info=exc)
        response = ErrorResponse(
            error=ErrorDetail(code="internal_error", message="خطای داخلی سرور")
        )
        return JSONResponse(status_code=500, content=response.model_dump())


app = create_app()
