"""Resolve effective apps and limits for one tenant."""

from __future__ import annotations

from datetime import datetime, timezone
from decimal import Decimal
from typing import Any

from sqlalchemy import select

from config.control_plane import get_control_plane_session
from bridge_platform.tenants.models import (
    App,
    Plan,
    Tenant,
    TenantApp,
    TenantLimit,
    TenantSubscription,
)
from bridge_platform.quotas.service import usage_snapshot
from bridge_platform.storage.service import get_storage_snapshot
from bridge_platform.billing.lifecycle import evaluate_subscription
from bridge_platform.billing.stripe_adapter import stripe_readiness


def get_effective_entitlements(tenant_id: str) -> dict[str, Any]:
    with get_control_plane_session() as session:
        tenant = session.get(Tenant, tenant_id)
        if tenant is None:
            raise LookupError(f"Tenant not found: {tenant_id}")

        subscription = session.execute(
            select(TenantSubscription)
            .where(TenantSubscription.tenant_id == tenant_id)
            .limit(1)
        ).scalar_one_or_none()
        plan = session.get(Plan, subscription.plan_id) if subscription else None

        catalog = session.execute(
            select(App).where(App.is_active.is_(True)).order_by(App.display_name)
        ).scalars().all()
        tenant_apps = session.execute(
            select(TenantApp).where(TenantApp.tenant_id == tenant_id)
        ).scalars().all()
        app_bindings = {binding.app_id: binding for binding in tenant_apps}

        limits = session.execute(
            select(TenantLimit).where(TenantLimit.tenant_id == tenant_id)
        ).scalars().all()

        subscription_status = subscription.status if subscription else "missing"
        lifecycle = evaluate_subscription(
            subscription_status,
            subscription.metadata_json if subscription else None,
        )
        subscription_active = lifecycle["access_allowed"]
        payload = {
            "tenant_id": tenant.tenant_id,
            "generated_at": datetime.now(timezone.utc).isoformat(),
            "subscription": {
                "status": subscription_status,
                "active": subscription_active,
                "in_grace_period": lifecycle["in_grace_period"],
                "grace_until": lifecycle["grace_until"],
                "access_reason": lifecycle["access_reason"],
                "provider": subscription.provider if subscription else None,
                "plan": {
                    "id": plan.plan_id if plan else tenant.plan_id,
                    "code": plan.code if plan else None,
                    "name": plan.name if plan else None,
                    "currency": plan.currency if plan else None,
                    "price_monthly": _number(plan.price_monthly) if plan else None,
                },
                "current_period_start": _iso(subscription.current_period_start) if subscription else None,
                "current_period_end": _iso(subscription.current_period_end) if subscription else None,
                "cancel_at_period_end": bool(subscription.cancel_at_period_end) if subscription else False,
            },
            "apps": [
                _app_payload(
                    app,
                    app_bindings.get(app.app_id),
                    subscription_active=subscription_active,
                )
                for app in catalog
            ],
            "limits": {
                record.limit_name: {
                    "value": record.limit_value,
                    "window_seconds": record.window_seconds,
                    "overage_policy": record.overage_policy,
                    "app_id": record.app_id,
                }
                for record in limits
            },
        }
    payload["usage"] = usage_snapshot(tenant_id)
    payload["usage"]["storage_mb"] = get_storage_snapshot(tenant_id).to_dict()
    payload["billing"] = stripe_readiness()
    return payload


def subscription_allows_app(tenant_id: str, app_id: str) -> bool:
    entitlements = get_effective_entitlements(tenant_id)
    if not entitlements["subscription"]["active"]:
        return False
    return any(
        app["app_id"] == app_id and app["enabled"]
        for app in entitlements["apps"]
    )


def _app_payload(
    app: App,
    binding: TenantApp | None,
    *,
    subscription_active: bool,
) -> dict[str, Any]:
    metadata = dict(app.metadata_json or {})
    return {
        "app_id": app.app_id,
        "name": app.display_name,
        "description": metadata.get("description") or "",
        "category": metadata.get("category") or "business",
        "enabled": bool(binding and binding.is_enabled and subscription_active),
        "route_prefix": app.route_prefix,
        "config": binding.config_json or {} if binding else {},
    }


def _number(value):
    if isinstance(value, Decimal):
        return float(value)
    return value


def _iso(value: datetime | None) -> str | None:
    return value.isoformat() if value else None
