"""Request context builder for the SaaS gateway runtime flow."""

from __future__ import annotations

from pathlib import Path
from uuid import uuid4

from flask import Request
from sqlalchemy import select
from sqlalchemy.orm import Session

from config.control_plane import get_control_plane_engine
from platform.tenants.models import TenantApp, TenantLimit


BASE_DIR = Path("/var/www/html/flask_server")


def build_request_context(request: Request, tenant_data: dict[str, str]) -> dict[str, object]:
    """Build a normalized request context for downstream app handlers."""
    request_id = (request.headers.get("X-Request-ID") or "").strip() or str(uuid4())
    app_id = (request.headers.get("X-App-ID") or "").strip()
    if not app_id:
        raise ValueError("Missing X-App-ID header")

    user_id = (request.headers.get("X-User-ID") or "").strip() or None
    tenant_key = tenant_data.get("storage_key") or tenant_data.get("slug") or tenant_data["tenant_id"]

    storage_path = BASE_DIR / "storage" / "tenants" / tenant_key
    logs_path = BASE_DIR / "logs" / "tenants" / tenant_key

    engine = get_control_plane_engine()
    with Session(engine, future=True) as session:
        limits = _load_limits(session, tenant_id=tenant_data["tenant_id"], app_id=app_id)
        app_config = _load_app_config(session, tenant_id=tenant_data["tenant_id"], app_id=app_id)

    return {
        "request_id": request_id,
        "tenant": tenant_data,
        "db": tenant_data.get("db_name") or "",
        "storage": str(storage_path),
        "logs": str(logs_path),
        "app_id": app_id,
        "user_id": user_id,
        "limits": limits,
        "app_config": app_config,
    }


def _load_limits(session: Session, *, tenant_id: str, app_id: str) -> dict[str, dict[str, object]]:
    stmt = select(TenantLimit).where(TenantLimit.tenant_id == tenant_id)
    records = session.execute(stmt).scalars().all()

    scoped: dict[str, dict[str, object]] = {}
    for record in records:
        if record.app_id not in (None, app_id):
            continue
        scoped[record.limit_name] = {
            "limit_value": record.limit_value,
            "window_seconds": record.window_seconds,
            "overage_policy": record.overage_policy,
            "app_id": record.app_id,
        }
    return scoped


def _load_app_config(session: Session, *, tenant_id: str, app_id: str) -> dict[str, object]:
    stmt = (
        select(TenantApp)
        .where(
            TenantApp.tenant_id == tenant_id,
            TenantApp.app_id == app_id,
        )
        .limit(1)
    )
    record = session.execute(stmt).scalar_one_or_none()
    if record is None:
        return {"enabled": False}
    return {
        "enabled": bool(record.is_enabled),
        "config": record.config_json or {},
    }
