# tests/integration/api/v1/platform/test_pricing.py
"""Integration tests for platform pricing API endpoints.

Tests the /api/v1/platform/pricing/* endpoints.
"""

import pytest

from app.modules.billing.models import (
    AddOnProduct,
    SubscriptionTier,
    TierCode,
    TIER_LIMITS,
)


@pytest.mark.integration
@pytest.mark.api
@pytest.mark.platform
class TestPlatformPricingAPI:
    """Test platform pricing endpoints at /api/v1/platform/*."""

    # =========================================================================
    # GET /api/v1/platform/pricing/tiers
    # =========================================================================

    def test_get_tiers_returns_all_public_tiers(self, client):
        """Test getting all subscription tiers."""
        response = client.get("/api/v1/platform/pricing/tiers")

        assert response.status_code == 200
        data = response.json()
        assert isinstance(data, list)
        assert len(data) >= 4  # Essential, Professional, Business, Enterprise

    def test_get_tiers_has_expected_fields(self, client):
        """Test that tier response has all expected fields."""
        response = client.get("/api/v1/platform/pricing/tiers")

        assert response.status_code == 200
        data = response.json()
        assert len(data) > 0

        tier = data[0]
        assert "code" in tier
        assert "name" in tier
        assert "price_monthly" in tier
        assert "price_monthly_cents" in tier
        assert "orders_per_month" in tier
        assert "products_limit" in tier
        assert "team_members" in tier
        assert "features" in tier
        assert "is_popular" in tier
        assert "is_enterprise" in tier

    def test_get_tiers_includes_essential(self, client):
        """Test that Essential tier is included."""
        response = client.get("/api/v1/platform/pricing/tiers")

        assert response.status_code == 200
        data = response.json()
        tier_codes = [t["code"] for t in data]
        assert TierCode.ESSENTIAL.value in tier_codes

    def test_get_tiers_includes_professional(self, client):
        """Test that Professional tier is included and marked as popular."""
        response = client.get("/api/v1/platform/pricing/tiers")

        assert response.status_code == 200
        data = response.json()

        professional = next(
            (t for t in data if t["code"] == TierCode.PROFESSIONAL.value), None
        )
        assert professional is not None
        assert professional["is_popular"] is True

    def test_get_tiers_includes_enterprise(self, client):
        """Test that Enterprise tier is included and marked appropriately."""
        response = client.get("/api/v1/platform/pricing/tiers")

        assert response.status_code == 200
        data = response.json()

        enterprise = next(
            (t for t in data if t["code"] == TierCode.ENTERPRISE.value), None
        )
        assert enterprise is not None
        assert enterprise["is_enterprise"] is True

    def test_get_tiers_from_database(self, client, db):
        """Test getting tiers from database when available."""
        # Create a tier in the database
        tier = SubscriptionTier(
            code="test_tier",
            name="Test Tier",
            description="A test tier",
            price_monthly_cents=9900,
            price_annual_cents=99000,
            orders_per_month=1000,
            products_limit=500,
            team_members=5,
            features=["feature1", "feature2"],
            is_active=True,
            is_public=True,
            display_order=99,
        )
        db.add(tier)
        db.commit()

        response = client.get("/api/v1/platform/pricing/tiers")

        assert response.status_code == 200
        data = response.json()
        tier_codes = [t["code"] for t in data]
        assert "test_tier" in tier_codes

    # =========================================================================
    # GET /api/v1/platform/pricing/tiers/{tier_code}
    # =========================================================================

    def test_get_tier_by_code_success(self, client):
        """Test getting a specific tier by code."""
        response = client.get(f"/api/v1/platform/pricing/tiers/{TierCode.PROFESSIONAL.value}")

        assert response.status_code == 200
        data = response.json()
        assert data["code"] == TierCode.PROFESSIONAL.value
        assert data["name"] == TIER_LIMITS[TierCode.PROFESSIONAL]["name"]

    def test_get_tier_by_code_essential(self, client):
        """Test getting Essential tier details."""
        response = client.get(f"/api/v1/platform/pricing/tiers/{TierCode.ESSENTIAL.value}")

        assert response.status_code == 200
        data = response.json()
        assert data["code"] == TierCode.ESSENTIAL.value
        assert data["price_monthly"] == TIER_LIMITS[TierCode.ESSENTIAL]["price_monthly_cents"] / 100

    def test_get_tier_by_code_not_found(self, client):
        """Test getting a non-existent tier returns 404."""
        response = client.get("/api/v1/platform/pricing/tiers/nonexistent_tier")

        assert response.status_code == 404
        data = response.json()
        assert "not found" in data["message"].lower()

    # =========================================================================
    # GET /api/v1/platform/pricing/addons
    # =========================================================================

    def test_get_addons_empty_when_none_configured(self, client):
        """Test getting add-ons when none are configured."""
        response = client.get("/api/v1/platform/pricing/addons")

        assert response.status_code == 200
        data = response.json()
        assert isinstance(data, list)

    def test_get_addons_returns_configured_addons(self, client, db):
        """Test getting add-ons when configured in database."""
        # Create test add-on
        addon = AddOnProduct(
            code="test_domain",
            name="Custom Domain",
            description="Use your own domain",
            category="domain",
            price_cents=1500,
            billing_period="annual",
            is_active=True,
            display_order=1,
        )
        db.add(addon)
        db.commit()

        response = client.get("/api/v1/platform/pricing/addons")

        assert response.status_code == 200
        data = response.json()
        assert len(data) >= 1

        addon_codes = [a["code"] for a in data]
        assert "test_domain" in addon_codes

    def test_get_addons_has_expected_fields(self, client, db):
        """Test that addon response has all expected fields."""
        addon = AddOnProduct(
            code="test_ssl",
            name="Premium SSL",
            description="EV certificate",
            category="security",
            price_cents=4900,
            billing_period="annual",
            is_active=True,
            display_order=1,
        )
        db.add(addon)
        db.commit()

        response = client.get("/api/v1/platform/pricing/addons")

        assert response.status_code == 200
        data = response.json()
        assert len(data) > 0

        addon_response = data[0]
        assert "code" in addon_response
        assert "name" in addon_response
        assert "description" in addon_response
        assert "category" in addon_response
        assert "price" in addon_response
        assert "price_cents" in addon_response
        assert "billing_period" in addon_response

    def test_get_addons_excludes_inactive(self, client, db):
        """Test that inactive add-ons are excluded."""
        # Create active and inactive add-ons
        active_addon = AddOnProduct(
            code="active_addon",
            name="Active Addon",
            category="test",
            price_cents=1000,
            billing_period="monthly",
            is_active=True,
            display_order=1,
        )
        inactive_addon = AddOnProduct(
            code="inactive_addon",
            name="Inactive Addon",
            category="test",
            price_cents=1000,
            billing_period="monthly",
            is_active=False,
            display_order=2,
        )
        db.add_all([active_addon, inactive_addon])
        db.commit()

        response = client.get("/api/v1/platform/pricing/addons")

        assert response.status_code == 200
        data = response.json()
        addon_codes = [a["code"] for a in data]
        assert "active_addon" in addon_codes
        assert "inactive_addon" not in addon_codes

    # =========================================================================
    # GET /api/v1/platform/pricing
    # =========================================================================

    def test_get_pricing_returns_complete_info(self, client):
        """Test getting complete pricing information."""
        response = client.get("/api/v1/platform/pricing")

        assert response.status_code == 200
        data = response.json()

        assert "tiers" in data
        assert "addons" in data
        assert "trial_days" in data
        assert "annual_discount_months" in data

    def test_get_pricing_includes_trial_days(self, client):
        """Test that pricing includes correct trial period."""
        response = client.get("/api/v1/platform/pricing")

        assert response.status_code == 200
        data = response.json()
        assert data["trial_days"] == 30  # Updated from 14 to 30

    def test_get_pricing_includes_annual_discount(self, client):
        """Test that pricing includes annual discount info."""
        response = client.get("/api/v1/platform/pricing")

        assert response.status_code == 200
        data = response.json()
        assert data["annual_discount_months"] == 2  # 2 months free

    def test_get_pricing_tiers_not_empty(self, client):
        """Test that pricing always includes tiers."""
        response = client.get("/api/v1/platform/pricing")

        assert response.status_code == 200
        data = response.json()
        assert len(data["tiers"]) >= 4
