"""Read-only query selectors for the modules app.

NOTE ON LICENSING
-----------------
``TenantModule`` is for provisioning/migrations only — NOT for licensing.
Feature availability is determined exclusively by the Feature Resolution
Algorithm in ``simorgh.apps.subscription.selectors.is_feature_enabled``.

``is_feature_enabled`` below is a thin compatibility shim that delegates
to the subscription layer.  Do **not** check ``TenantModule.status`` for
licensing decisions.
"""

from __future__ import annotations

from django.db.models import QuerySet

from simorgh.apps.modules.models import FeatureCatalog, ModuleStatus, TenantModule

__all__ = [
    "get_enabled_modules",
    "get_module_by_name",
    "is_feature_enabled",
    "list_features",
]


def get_enabled_modules(tenant_id: int) -> QuerySet:
    """Return all TenantModule records with status=ENABLED for a tenant.

    This reflects provisioning state only — enabled modules do NOT
    automatically grant feature entitlements.
    """
    return TenantModule.objects.filter(
        tenant_id=tenant_id, status=ModuleStatus.ENABLED
    ).order_by("name")


def get_module_by_name(tenant_id: int, name: str) -> TenantModule | None:
    """Return the installed TenantModule for a tenant by name, or ``None``."""
    return TenantModule.objects.filter(tenant_id=tenant_id, name=name).first()


def is_feature_enabled(tenant_id: int, feature_key: str) -> bool:
    """Return whether a feature is enabled for a tenant.

    Delegates to the subscription Feature Resolution Algorithm (6 steps).
    TenantModule.status is NOT consulted for licensing — modules are
    provisioning units only.

    For per-user granularity use ``is_feature_enabled_for_user()``.
    """
    from simorgh.apps.subscription.selectors import (
        is_feature_enabled as _sub_is_feature_enabled,
    )
    from simorgh.apps.tenants.models import Tenant

    try:
        tenant = Tenant.objects.get(pk=tenant_id)
    except Tenant.DoesNotExist:
        return False

    return _sub_is_feature_enabled(tenant, feature_key)


def is_feature_enabled_for_user(tenant_id: int, feature_key: str, user_id: int) -> bool:
    """Return whether a feature is enabled for a specific user on a tenant.

    Per-user TenantFeatureOverride rows are checked first; falls back to
    the standard tenant-level resolution.

    Feature keys are resolved through the backward-compat alias layer.
    """
    from simorgh.apps.modules.compat import resolve_feature_key
    from simorgh.apps.modules.models import TenantFeatureOverride

    feature_key = resolve_feature_key(feature_key)

    # Per-user override — checked before the tenant-level algorithm.
    override = (
        TenantFeatureOverride.objects.filter(
            tenant_id=tenant_id,
            feature_key=feature_key,
            user_id=user_id,
        )
        .only("enabled")
        .first()
    )
    if override is not None:
        return override.enabled

    return is_feature_enabled(tenant_id, feature_key)


def list_features(*, module_name: str | None = None) -> QuerySet:
    """Return all registered FeatureCatalog entries, optionally filtered by module."""
    qs = FeatureCatalog.objects.all()
    if module_name:
        qs = qs.filter(module_name=module_name)
    return qs.order_by("module_name", "code")

