"""Standalone subscription and app-entitlement checks."""

from __future__ import annotations

import sys
import unittest
from pathlib import Path


PROJECT_ROOT = Path(__file__).resolve().parents[2]
sys.path.insert(0, str(PROJECT_ROOT))
loaded_platform = sys.modules.get("platform")
if loaded_platform is not None and not hasattr(loaded_platform, "__path__"):
    del sys.modules["platform"]

from sqlalchemy import create_engine
from sqlalchemy.orm import Session
from sqlalchemy.pool import StaticPool

from config.db import Base
from platform.entitlements import service
from platform.quotas import service as quota_service
from platform.tenants.models import (
    App,
    Plan,
    Tenant,
    TenantApp,
    TenantLimit,
    TenantSubscription,
)


class EntitlementChecks(unittest.TestCase):
    def setUp(self):
        self.engine = create_engine(
            "sqlite://",
            connect_args={"check_same_thread": False},
            poolclass=StaticPool,
            future=True,
        )
        Base.metadata.create_all(self.engine)
        self.original_session_factory = service.get_control_plane_session
        self.original_quota_session_factory = quota_service.get_control_plane_session
        self.original_storage_snapshot = service.get_storage_snapshot
        self.original_stripe_readiness = service.stripe_readiness
        service.get_control_plane_session = lambda: Session(self.engine, future=True)
        quota_service.get_control_plane_session = lambda: Session(self.engine, future=True)
        service.get_storage_snapshot = lambda tenant_id: type(
            "Snapshot", (), {"to_dict": lambda self: {
                "metric": "storage_bytes", "used_mb": 0,
                "remaining_mb": 512, "limit_mb": 512, "status": "available",
            }}
        )()
        service.stripe_readiness = lambda: {
            "provider": "stripe", "ready_for_webhooks": False,
            "prices_configured": False, "live_payments_enabled": False,
        }
        with Session(self.engine, future=True) as session:
            session.add(Plan(plan_id="plan-a", code="plan-a", name="Plan A"))
            session.add(
                Tenant(
                    tenant_id="tenant-a",
                    slug="tenant-a",
                    name="Tenant A",
                    status="active",
                    is_active=True,
                    plan_id="plan-a",
                )
            )
            session.add(
                App(
                    app_id="allowed-app",
                    display_name="Allowed App",
                    module_path="apps.allowed",
                    route_prefix="/api/v1/allowed-app",
                    is_active=True,
                )
            )
            session.add(
                TenantSubscription(
                    subscription_id="sub-a",
                    tenant_id="tenant-a",
                    plan_id="plan-a",
                    provider="manual",
                    status="active",
                )
            )
            session.add(TenantApp(tenant_id="tenant-a", app_id="allowed-app", is_enabled=True))
            session.add(
                TenantLimit(
                    tenant_id="tenant-a",
                    app_id=None,
                    limit_name="storage_mb",
                    limit_value=512,
                    overage_policy="block",
                )
            )
            session.commit()

    def tearDown(self):
        service.get_control_plane_session = self.original_session_factory
        quota_service.get_control_plane_session = self.original_quota_session_factory
        service.get_storage_snapshot = self.original_storage_snapshot
        service.stripe_readiness = self.original_stripe_readiness
        self.engine.dispose()

    def test_active_subscription_enables_bound_app(self):
        payload = service.get_effective_entitlements("tenant-a")
        self.assertTrue(payload["subscription"]["active"])
        self.assertTrue(payload["apps"][0]["enabled"])
        self.assertEqual(512, payload["limits"]["storage_mb"]["value"])

    def test_inactive_subscription_disables_bound_app(self):
        with Session(self.engine, future=True) as session:
            subscription = session.get(TenantSubscription, "sub-a")
            subscription.status = "canceled"
            session.commit()
        self.assertFalse(service.subscription_allows_app("tenant-a", "allowed-app"))


if __name__ == "__main__":
    unittest.main(verbosity=2)
