"""
Test Pricing Unification

These tests verify that pricing multipliers are consistent across all modules:
- billing.py: Uses Decimal percentages (50%, 30%)
- selection.py: Uses multipliers (1.50, 1.30)
- queue.py: Uses PricingMultiplier dataclass (1.50, 1.30)
- billing_api.py: Returns percentage-based margins (50%, 30%)

Two-mode pricing system:
- Performance (fast=True):  +50% margin (immediate execution)
- Standard (fast=False):    +30% margin (can wait up to 10 min)
"""

from decimal import Decimal

import pytest


class TestPricingConsistency:
    """Test that pricing is consistent across all modules."""

    def test_billing_gateway_margins(self):
        """Test that billing.py GATEWAY_MARGIN_PERCENT values are correct."""
        from verlex_server.gateway.backend.billing import GATEWAY_MARGIN_PERCENT, ExecutionMode

        expected = {
            ExecutionMode.PERFORMANCE: Decimal("0.50"),  # 50% margin (immediate)
            ExecutionMode.STANDARD: Decimal("0.30"),     # 30% margin (can wait)
        }

        assert GATEWAY_MARGIN_PERCENT == expected, (
            f"GATEWAY_MARGIN_PERCENT mismatch. Expected: {expected}, Got: {GATEWAY_MARGIN_PERCENT}"
        )

    def test_selection_pricing_multipliers(self):
        """Test that selection.py PRICING_MULTIPLIERS match billing margins."""
        from verlex_server.gateway.core.selection import PRICING_MULTIPLIERS, SelectionMode

        expected = {
            SelectionMode.PERFORMANCE: 1.50,  # 50% margin (immediate)
            SelectionMode.STANDARD: 1.30,     # 30% margin (can wait)
        }

        for mode, expected_mult in expected.items():
            actual_mult = PRICING_MULTIPLIERS[mode]
            assert actual_mult == pytest.approx(expected_mult, abs=0.001), (
                f"PRICING_MULTIPLIERS[{mode}] mismatch. Expected: {expected_mult}, Got: {actual_mult}"
            )

    def test_queue_pricing_multipliers(self):
        """Test that queue.py PricingMultiplier values match billing margins."""
        from verlex_server.gateway.core.queue import PricingMultiplier

        multiplier = PricingMultiplier()

        assert multiplier.PERFORMANCE_MULTIPLIER == pytest.approx(1.50, abs=0.001), (
            f"PERFORMANCE_MULTIPLIER mismatch. Expected: 1.50, Got: {multiplier.PERFORMANCE_MULTIPLIER}"
        )
        assert multiplier.STANDARD_MULTIPLIER == pytest.approx(1.30, abs=0.001), (
            f"STANDARD_MULTIPLIER mismatch. Expected: 1.30, Got: {multiplier.STANDARD_MULTIPLIER}"
        )

    def test_pricing_multipliers_cross_module_consistency(self):
        """Test that all modules use the same pricing multipliers."""
        from verlex_server.gateway.backend.billing import GATEWAY_MARGIN_PERCENT
        from verlex_server.gateway.backend.billing import ExecutionMode as BillingMode
        from verlex_server.gateway.core.queue import PricingMultiplier
        from verlex_server.gateway.core.selection import PRICING_MULTIPLIERS, SelectionMode

        queue_mult = PricingMultiplier()

        mode_mapping = {
            BillingMode.PERFORMANCE: SelectionMode.PERFORMANCE,
            BillingMode.STANDARD: SelectionMode.STANDARD,
        }

        queue_multipliers = {
            BillingMode.PERFORMANCE: queue_mult.PERFORMANCE_MULTIPLIER,
            BillingMode.STANDARD: queue_mult.STANDARD_MULTIPLIER,
        }

        for billing_mode, selection_mode in mode_mapping.items():
            billing_margin = GATEWAY_MARGIN_PERCENT[billing_mode]
            expected_mult = 1 + float(billing_margin)

            selection_mult = PRICING_MULTIPLIERS[selection_mode]
            assert selection_mult == pytest.approx(expected_mult, abs=0.001), (
                f"selection.py {billing_mode} mismatch. Expected: {expected_mult}, Got: {selection_mult}"
            )

            queue_mult_value = queue_multipliers[billing_mode]
            assert queue_mult_value == pytest.approx(expected_mult, abs=0.001), (
                f"queue.py {billing_mode} mismatch. Expected: {expected_mult}, Got: {queue_mult_value}"
            )


class TestModeCodeUnification:
    """Test that mode codes are unified across all modules."""

    def test_auth_execution_mode_includes_p_and_s(self):
        """Test that auth.py ExecutionMode includes P and S."""
        from typing import get_args

        from verlex_server.gateway.client.auth import ExecutionMode

        valid_modes = get_args(ExecutionMode)

        assert "P" in valid_modes, f"'P' not in ExecutionMode: {valid_modes}"
        assert "S" in valid_modes, f"'S' not in ExecutionMode: {valid_modes}"

    def test_legacy_mode_normalization(self):
        """Test that legacy modes map to Standard."""
        from verlex_server.gateway.backend.billing import PricingEngine

        engine = PricingEngine()

        # Legacy codes should all map to Standard (30%)
        for legacy_code in ["Pa", "N", "F"]:
            margin = engine.get_margin_for_mode(legacy_code)
            assert margin == Decimal("0.30"), (
                f"Legacy mode '{legacy_code}' should map to 30% (Standard), got {margin}"
            )

        # Performance code
        margin = engine.get_margin_for_mode("P")
        assert margin == Decimal("0.50"), (
            f"Performance mode 'P' should be 50%, got {margin}"
        )


class TestBillingApiPricingModes:
    """Test the /pricing/modes API endpoint returns correct data."""

    def test_pricing_modes_returns_percentages(self):
        """Test that /pricing/modes returns percentage-based margins."""
        import asyncio

        from verlex_server.gateway.backend.billing_api import get_pricing_modes

        result = asyncio.get_event_loop().run_until_complete(get_pricing_modes())

        modes = result["modes"]

        # Check Performance mode (50%)
        assert modes["P"]["margin_percent"] == 50, f"P margin should be 50, got {modes['P']['margin_percent']}"
        assert modes["P"]["multiplier"] == pytest.approx(1.50, abs=0.001)

        # Check Standard mode (30%)
        assert modes["S"]["margin_percent"] == 30, f"S margin should be 30, got {modes['S']['margin_percent']}"
        assert modes["S"]["multiplier"] == pytest.approx(1.30, abs=0.001)

    def test_pricing_modes_only_two_modes(self):
        """Test that only Performance and Standard modes exist."""
        import asyncio

        from verlex_server.gateway.backend.billing_api import get_pricing_modes

        result = asyncio.get_event_loop().run_until_complete(get_pricing_modes())

        modes = result["modes"]
        assert set(modes.keys()) == {"P", "S"}, f"Expected only P and S modes, got {set(modes.keys())}"

    def test_pricing_modes_formula_is_multiplication(self):
        """Test that the pricing formula uses multiplication."""
        import asyncio

        from verlex_server.gateway.backend.billing_api import get_pricing_modes

        result = asyncio.get_event_loop().run_until_complete(get_pricing_modes())

        formula = result["formula"]
        assert "×" in formula or "*" in formula, f"Formula should use multiplication: {formula}"

    def test_pricing_modes_no_flat_margin(self):
        """Test that /pricing/modes does NOT return flat margin_per_hour."""
        import asyncio

        from verlex_server.gateway.backend.billing_api import get_pricing_modes

        result = asyncio.get_event_loop().run_until_complete(get_pricing_modes())

        for mode_code, mode_info in result["modes"].items():
            assert "margin_per_hour" not in mode_info, (
                f"Mode {mode_code} should not have 'margin_per_hour'"
            )


class TestPricingCalculations:
    """Test actual pricing calculations use correct multipliers."""

    def test_performance_price_is_50_percent_premium(self):
        """Test Performance mode adds 50% to base cost."""
        from verlex_server.gateway.core.queue import PricingMultiplier

        mult = PricingMultiplier()
        base_cost = 1.00

        performance_cost = base_cost * mult.PERFORMANCE_MULTIPLIER

        assert performance_cost == pytest.approx(1.50, abs=0.001), (
            f"Performance cost should be $1.50 (50% premium), got ${performance_cost}"
        )

    def test_standard_price_is_30_percent_premium(self):
        """Test Standard mode adds 30% to base cost."""
        from verlex_server.gateway.core.queue import PricingMultiplier

        mult = PricingMultiplier()
        base_cost = 1.00

        standard_cost = base_cost * mult.STANDARD_MULTIPLIER

        assert standard_cost == pytest.approx(1.30, abs=0.001), (
            f"Standard cost should be $1.30 (30% premium), got ${standard_cost}"
        )


if __name__ == "__main__":
    pytest.main([__file__, "-v"])
