from decimal import Decimal
from django.test import TestCase
from django.utils import timezone

from ..models.base import Currency, Term, Unit
from ..models.providers import CloudProvider
from ..models.services import Service, Category
from ..models.pricing import (
    ComputePlan,
    ComputePlanPrice,
    ComputePlanGroup,
    StoragePlan,
    StoragePlanPrice,
    ProgressiveDiscountModel,
    DiscountTier,
    VSHNAppCatPrice,
    VSHNAppCatBaseFee,
    VSHNAppCatUnitRate,
    VSHNAppCatAddon,
    VSHNAppCatAddonBaseFee,
    VSHNAppCatAddonUnitRate,
    ExternalPricePlans,
)


class PricingIntegrationTestCase(TestCase):
    """Integration tests for pricing models working together"""

    def setUp(self):
        """Set up test data for integration tests"""
        # Create cloud provider
        self.cloud_provider = CloudProvider.objects.create(
            name="VSHN Cloud",
            slug="vshn-cloud",
            description="Swiss cloud provider",
            website="https://vshn.ch",
            is_featured=True,
        )

        # Create service category
        self.database_category = Category.objects.create(
            name="Databases", slug="databases", description="Database services"
        )

        # Create database service
        self.postgresql_service = Service.objects.create(
            name="PostgreSQL",
            slug="postgresql",
            description="Managed PostgreSQL database service",
            tagline="Reliable, scalable PostgreSQL",
            features="High availability, automated backups, monitoring",
            is_featured=True,
        )
        self.postgresql_service.categories.add(self.database_category)

        # Create compute plan group
        self.standard_group = ComputePlanGroup.objects.create(
            name="Standard",
            description="Standard compute plans",
            node_label="standard",
            order=1,
        )

        # Create multiple compute plans
        self.small_plan = ComputePlan.objects.create(
            name="Small",
            vcpus=1.0,
            ram=2.0,
            cpu_mem_ratio=0.5,
            cloud_provider=self.cloud_provider,
            group=self.standard_group,
            term=Term.MTH,
            active=True,
        )

        self.medium_plan = ComputePlan.objects.create(
            name="Medium",
            vcpus=2.0,
            ram=4.0,
            cpu_mem_ratio=0.5,
            cloud_provider=self.cloud_provider,
            group=self.standard_group,
            term=Term.MTH,
            active=True,
        )

        self.large_plan = ComputePlan.objects.create(
            name="Large",
            vcpus=4.0,
            ram=8.0,
            cpu_mem_ratio=0.5,
            cloud_provider=self.cloud_provider,
            group=self.standard_group,
            term=Term.MTH,
            active=True,
        )

        # Create storage plan
        self.ssd_storage = StoragePlan.objects.create(
            name="SSD Storage",
            cloud_provider=self.cloud_provider,
            term=Term.MTH,
            unit=Unit.GIB,
        )

        # Create progressive discount model for AppCat
        self.ram_discount_model = ProgressiveDiscountModel.objects.create(
            name="RAM Volume Discount",
            description="Progressive discount for RAM usage",
            active=True,
        )

        # Create discount tiers
        DiscountTier.objects.create(
            discount_model=self.ram_discount_model,
            min_units=0,
            max_units=8,
            discount_percent=Decimal("0.00"),  # 0-7 GiB: no discount
        )

        DiscountTier.objects.create(
            discount_model=self.ram_discount_model,
            min_units=8,
            max_units=32,
            discount_percent=Decimal("10.00"),  # 8-31 GiB: 10% discount
        )

        DiscountTier.objects.create(
            discount_model=self.ram_discount_model,
            min_units=32,
            max_units=None,
            discount_percent=Decimal("20.00"),  # 32+ GiB: 20% discount
        )

    def test_complete_pricing_setup(self):
        """Test complete pricing setup for all models"""
        # Set up compute plan prices
        ComputePlanPrice.objects.create(
            compute_plan=self.small_plan, currency=Currency.CHF, amount=Decimal("50.00")
        )

        ComputePlanPrice.objects.create(
            compute_plan=self.medium_plan,
            currency=Currency.CHF,
            amount=Decimal("100.00"),
        )

        ComputePlanPrice.objects.create(
            compute_plan=self.large_plan,
            currency=Currency.CHF,
            amount=Decimal("200.00"),
        )

        # Set up storage pricing
        StoragePlanPrice.objects.create(
            storage_plan=self.ssd_storage,
            currency=Currency.CHF,
            amount=Decimal("0.20"),  # 0.20 CHF per GiB
        )

        # Verify all prices are retrievable
        self.assertEqual(self.small_plan.get_price(Currency.CHF), Decimal("50.00"))
        self.assertEqual(self.medium_plan.get_price(Currency.CHF), Decimal("100.00"))
        self.assertEqual(self.large_plan.get_price(Currency.CHF), Decimal("200.00"))
        self.assertEqual(self.ssd_storage.get_price(Currency.CHF), Decimal("0.20"))

    def test_multi_currency_pricing(self):
        """Test pricing in multiple currencies"""
        # Set up prices in CHF, EUR, and USD
        currencies_and_rates = [
            (Currency.CHF, Decimal("100.00")),
            (Currency.EUR, Decimal("95.00")),
            (Currency.USD, Decimal("110.00")),
        ]

        for currency, amount in currencies_and_rates:
            ComputePlanPrice.objects.create(
                compute_plan=self.medium_plan, currency=currency, amount=amount
            )

        # Verify all currencies are available
        for currency, expected_amount in currencies_and_rates:
            self.assertEqual(self.medium_plan.get_price(currency), expected_amount)

    def test_appcat_service_with_complete_pricing(self):
        """Test complete AppCat service pricing with all features"""
        # Create AppCat price configuration
        appcat_price = VSHNAppCatPrice.objects.create(
            service=self.postgresql_service,
            variable_unit=VSHNAppCatPrice.VariableUnit.RAM,
            term=Term.MTH,
            discount_model=self.ram_discount_model,
            ha_replica_min=1,
            ha_replica_max=3,
            public_display_enabled=True,
        )

        # Set up base fees for different currencies
        base_fees = [
            (Currency.CHF, Decimal("25.00")),
            (Currency.EUR, Decimal("22.50")),
            (Currency.USD, Decimal("27.50")),
        ]

        for currency, amount in base_fees:
            VSHNAppCatBaseFee.objects.create(
                vshn_appcat_price_config=appcat_price, currency=currency, service_level=VSHNAppCatPrice.ServiceLevel.BEST_EFFORT, amount=amount
            )
            VSHNAppCatBaseFee.objects.create(
                vshn_appcat_price_config=appcat_price, currency=currency, service_level=VSHNAppCatPrice.ServiceLevel.GUARANTEED, amount=amount
            )

        # Set up unit rates for different service levels and currencies
        unit_rates = [
            (Currency.CHF, VSHNAppCatPrice.ServiceLevel.BEST_EFFORT, Decimal("3.5000")),
            (Currency.CHF, VSHNAppCatPrice.ServiceLevel.GUARANTEED, Decimal("5.0000")),
            (Currency.EUR, VSHNAppCatPrice.ServiceLevel.BEST_EFFORT, Decimal("3.2000")),
            (Currency.EUR, VSHNAppCatPrice.ServiceLevel.GUARANTEED, Decimal("4.5000")),
            (Currency.USD, VSHNAppCatPrice.ServiceLevel.BEST_EFFORT, Decimal("3.8000")),
            (Currency.USD, VSHNAppCatPrice.ServiceLevel.GUARANTEED, Decimal("5.5000")),
        ]

        for currency, service_level, amount in unit_rates:
            VSHNAppCatUnitRate.objects.create(
                vshn_appcat_price_config=appcat_price,
                currency=currency,
                service_level=service_level,
                amount=amount,
            )

        # Create mandatory addon (backup)
        backup_addon = VSHNAppCatAddon.objects.create(
            vshn_appcat_price_config=appcat_price,
            name="Automated Backup",
            description="Daily automated backups with 30-day retention",
            commercial_description="Never lose your data with automated daily backups",
            addon_type=VSHNAppCatAddon.AddonType.BASE_FEE,
            mandatory=True,
            order=1,
        )

        VSHNAppCatAddonBaseFee.objects.create(
            addon=backup_addon, currency=Currency.CHF, service_level=VSHNAppCatPrice.ServiceLevel.GUARANTEED, amount=Decimal("15.00")
        )

        # Create optional addon (monitoring)
        monitoring_addon = VSHNAppCatAddon.objects.create(
            vshn_appcat_price_config=appcat_price,
            name="Advanced Monitoring",
            description="Detailed monitoring with custom alerts",
            commercial_description="Get insights into your database performance",
            addon_type=VSHNAppCatAddon.AddonType.UNIT_RATE,
            mandatory=False,
            order=2,
        )

        VSHNAppCatAddonUnitRate.objects.create(
            addon=monitoring_addon,
            currency=Currency.CHF,
            service_level=VSHNAppCatPrice.ServiceLevel.GUARANTEED,
            amount=Decimal("0.5000"),
        )

        # Test price calculation scenarios

        # Scenario 1: Small setup (4 GiB RAM, no discount)
        result_small = appcat_price.calculate_final_price(
            Currency.CHF, VSHNAppCatPrice.ServiceLevel.GUARANTEED, 4
        )

        # Base: 25 + (5 * 4) = 45
        # Mandatory backup: 15
        # Total: 60
        self.assertEqual(result_small["total_price"], Decimal("60.00"))
        self.assertEqual(result_small["addon_total"], Decimal("15.00"))
        self.assertEqual(len(result_small["addon_breakdown"]), 1)

        # Scenario 2: Medium setup (16 GiB RAM, partial discount)
        result_medium = appcat_price.calculate_final_price(
            Currency.CHF, VSHNAppCatPrice.ServiceLevel.GUARANTEED, 16
        )

        # First 8 GiB at full rate: 5 * 8 = 40
        # Next 8 GiB at 90% (10% discount): 5 * 0.9 * 8 = 36
        # Unit cost: 76
        # Base: 25 + 76 = 101
        # Mandatory backup: 15
        # Total: 116
        self.assertEqual(result_medium["total_price"], Decimal("116.00"))

        # Scenario 3: Large setup with optional addon (40 GiB RAM, full discount tiers)
        result_large = appcat_price.calculate_final_price(
            Currency.CHF,
            VSHNAppCatPrice.ServiceLevel.GUARANTEED,
            40,
            addon_ids=[monitoring_addon.id],
        )

        # First 8 GiB at full rate: 5 * 8 = 40
        # Next 24 GiB at 90% (10% discount): 5 * 0.9 * 24 = 108
        # Next 8 GiB at 80% (20% discount): 5 * 0.8 * 8 = 32
        # Unit cost: 180
        # Base: 25 + 180 = 205
        # Mandatory backup: 15
        # Optional monitoring: 0.5 * 40 = 20
        # Total: 240
        self.assertEqual(result_large["total_price"], Decimal("240.00"))
        self.assertEqual(result_large["addon_total"], Decimal("35.00"))
        self.assertEqual(len(result_large["addon_breakdown"]), 2)

    def test_external_price_comparison_integration(self):
        """Test external price comparison with internal pricing"""
        # Set up internal pricing
        appcat_price = VSHNAppCatPrice.objects.create(
            service=self.postgresql_service,
            variable_unit=VSHNAppCatPrice.VariableUnit.RAM,
            term=Term.MTH,
        )

        VSHNAppCatBaseFee.objects.create(
            vshn_appcat_price_config=appcat_price,
            currency=Currency.USD,
            service_level=VSHNAppCatPrice.ServiceLevel.GUARANTEED,
            amount=Decimal("30.00"),
        )

        VSHNAppCatUnitRate.objects.create(
            vshn_appcat_price_config=appcat_price,
            currency=Currency.USD,
            service_level=VSHNAppCatPrice.ServiceLevel.GUARANTEED,
            amount=Decimal("4.0000"),
        )

        # Create external competitor pricing
        aws_provider = CloudProvider.objects.create(
            name="AWS",
            slug="aws",
            description="Amazon Web Services",
            website="https://aws.amazon.com",
        )

        external_price = ExternalPricePlans.objects.create(
            plan_name="RDS PostgreSQL db.t3.medium",
            description="AWS RDS PostgreSQL instance",
            source="https://aws.amazon.com/rds/postgresql/pricing/",
            cloud_provider=aws_provider,
            service=self.postgresql_service,
            vshn_appcat_price=appcat_price,
            service_level=VSHNAppCatPrice.ServiceLevel.GUARANTEED,
            currency=Currency.USD,
            term=Term.MTH,
            amount=Decimal("62.56"),  # Monthly cost for db.t3.medium
            vcpus=2.0,
            ram=4.0,  # 4 GiB RAM
            storage=20.0,  # 20 GiB storage included
            competitor_sla="99.95%",
            replicas=1,
        )

        # Compare internal vs external pricing for equivalent setup
        internal_result = appcat_price.calculate_final_price(
            Currency.USD,
            VSHNAppCatPrice.ServiceLevel.GUARANTEED,
            4,  # 4 GiB RAM to match external offering
        )

        # Internal: 30 + (4 * 4) = 46 USD
        internal_price = internal_result["total_price"]
        external_price_amount = external_price.amount

        self.assertEqual(internal_price, Decimal("46.00"))
        self.assertEqual(external_price_amount, Decimal("62.56"))

        # Verify our pricing is competitive
        self.assertLess(internal_price, external_price_amount)

    def test_service_availability_with_pricing(self):
        """Test service availability based on pricing configuration"""
        # Create service with pricing but not enabled for public display
        redis_service = Service.objects.create(
            name="Redis",
            slug="redis",
            description="In-memory data store",
            features="High performance caching",
        )

        redis_price = VSHNAppCatPrice.objects.create(
            service=redis_service,
            variable_unit=VSHNAppCatPrice.VariableUnit.RAM,
            term=Term.MTH,
            public_display_enabled=False,  # Private pricing
        )

        VSHNAppCatBaseFee.objects.create(
            vshn_appcat_price_config=redis_price,
            currency=Currency.CHF,
            service_level=VSHNAppCatPrice.ServiceLevel.GUARANTEED,
            amount=Decimal("20.00"),
        )

        # Service should exist but not be publicly available for pricing
        self.assertFalse(redis_price.public_display_enabled)

        # Enable public display
        redis_price.public_display_enabled = True
        redis_price.save()

        self.assertTrue(redis_price.public_display_enabled)

    def test_pricing_model_relationships(self):
        """Test all pricing model relationships work correctly"""
        # Verify cloud provider relationships
        self.assertEqual(self.cloud_provider.compute_plans.count(), 3)
        self.assertEqual(self.cloud_provider.storage_plans.count(), 1)

        # Verify service relationships
        self.assertTrue(hasattr(self.postgresql_service, "vshn_appcat_price"))

        # Verify compute plan group relationships
        self.assertEqual(self.standard_group.compute_plans.count(), 3)

        # Create and verify discount model relationships
        appcat_price = VSHNAppCatPrice.objects.create(
            service=self.postgresql_service,
            variable_unit=VSHNAppCatPrice.VariableUnit.RAM,
            term=Term.MTH,
            discount_model=self.ram_discount_model,
        )

        self.assertEqual(self.ram_discount_model.price_configs.count(), 1)
        self.assertEqual(self.ram_discount_model.tiers.count(), 3)

        # Test cascade deletions work properly
        service_id = self.postgresql_service.id
        appcat_price_id = appcat_price.id

        # Delete service should cascade to appcat price
        self.postgresql_service.delete()

        with self.assertRaises(VSHNAppCatPrice.DoesNotExist):
            VSHNAppCatPrice.objects.get(id=appcat_price_id)

    def test_comprehensive_pricing_scenario(self):
        """Test a comprehensive real-world pricing scenario"""
        # Company needs PostgreSQL with high availability
        # Requirements: 16 GiB RAM, automated backups, monitoring, SSL

        appcat_price = VSHNAppCatPrice.objects.create(
            service=self.postgresql_service,
            variable_unit=VSHNAppCatPrice.VariableUnit.RAM,
            term=Term.MTH,
            discount_model=self.ram_discount_model,
            ha_replica_min=2,
            ha_replica_max=3,
            public_display_enabled=True,
        )

        # Set up pricing
        VSHNAppCatBaseFee.objects.create(
            vshn_appcat_price_config=appcat_price,
            currency=Currency.CHF,
            service_level=VSHNAppCatPrice.ServiceLevel.GUARANTEED,
            amount=Decimal("40.00"),  # Base fee for managed service
        )

        VSHNAppCatUnitRate.objects.create(
            vshn_appcat_price_config=appcat_price,
            currency=Currency.CHF,
            service_level=VSHNAppCatPrice.ServiceLevel.GUARANTEED,
            amount=Decimal("6.0000"),  # CHF per GiB RAM
        )

        # Create all required addons
        backup_addon = VSHNAppCatAddon.objects.create(
            vshn_appcat_price_config=appcat_price,
            name="Enterprise Backup",
            addon_type=VSHNAppCatAddon.AddonType.BASE_FEE,
            mandatory=True,
            order=1,
        )

        VSHNAppCatAddonBaseFee.objects.create(
            addon=backup_addon, currency=Currency.CHF, service_level=VSHNAppCatPrice.ServiceLevel.GUARANTEED, amount=Decimal("25.00")
        )

        monitoring_addon = VSHNAppCatAddon.objects.create(
            vshn_appcat_price_config=appcat_price,
            name="Advanced Monitoring",
            addon_type=VSHNAppCatAddon.AddonType.UNIT_RATE,
            mandatory=False,
            order=2,
        )

        VSHNAppCatAddonUnitRate.objects.create(
            addon=monitoring_addon,
            currency=Currency.CHF,
            service_level=VSHNAppCatPrice.ServiceLevel.GUARANTEED,
            amount=Decimal("0.7500"),
        )

        ssl_addon = VSHNAppCatAddon.objects.create(
            vshn_appcat_price_config=appcat_price,
            name="SSL Certificate",
            addon_type=VSHNAppCatAddon.AddonType.BASE_FEE,
            mandatory=False,
            order=3,
        )

        VSHNAppCatAddonBaseFee.objects.create(
            addon=ssl_addon, currency=Currency.CHF, service_level=VSHNAppCatPrice.ServiceLevel.GUARANTEED, amount=Decimal("18.00")
        )

        # Calculate final price with all selected addons
        result = appcat_price.calculate_final_price(
            Currency.CHF,
            VSHNAppCatPrice.ServiceLevel.GUARANTEED,
            16,  # 16 GiB RAM
            addon_ids=[monitoring_addon.id, ssl_addon.id],
        )

        # Expected calculation:
        # Base fee: 40.00
        # RAM cost: First 8 at 6.00 = 48.00, Next 8 at 5.40 (10% discount) = 43.20
        # RAM total: 91.20
        # Mandatory backup: 25.00
        # Optional monitoring: 0.75 * 16 = 12.00
        # Optional SSL: 18.00
        # Total: 40.00 + 91.20 + 25.00 + 12.00 + 18.00 = 186.20

        self.assertEqual(result["total_price"], Decimal("186.20"))
        self.assertEqual(result["addon_total"], Decimal("55.00"))
        self.assertEqual(len(result["addon_breakdown"]), 3)

        # Verify addon breakdown details
        addon_names = [addon["name"] for addon in result["addon_breakdown"]]
        self.assertIn("Enterprise Backup", addon_names)
        self.assertIn("Advanced Monitoring", addon_names)
from decimal import Decimal
from django.test import TestCase
from django.utils import timezone

from ..models.base import Currency, Term, Unit
from ..models.providers import CloudProvider
from ..models.services import Service, Category
from ..models.pricing import (
    ComputePlan,
    ComputePlanPrice,
    ComputePlanGroup,
    StoragePlan,
    StoragePlanPrice,
    ProgressiveDiscountModel,
    DiscountTier,
    VSHNAppCatPrice,
    VSHNAppCatBaseFee,
    VSHNAppCatUnitRate,
    VSHNAppCatAddon,
    VSHNAppCatAddonBaseFee,
    VSHNAppCatAddonUnitRate,
    ExternalPricePlans,
)


class PricingIntegrationTestCase(TestCase):
    """Integration tests for pricing models working together"""

    def setUp(self):
        """Set up test data for integration tests"""
        # Create cloud provider
        self.cloud_provider = CloudProvider.objects.create(
            name="VSHN Cloud",
            slug="vshn-cloud",
            description="Swiss cloud provider",
            website="https://vshn.ch",
            is_featured=True,
        )

        # Create service category
        self.database_category = Category.objects.create(
            name="Databases", slug="databases", description="Database services"
        )

        # Create database service
        self.postgresql_service = Service.objects.create(
            name="PostgreSQL",
            slug="postgresql",
            description="Managed PostgreSQL database service",
            tagline="Reliable, scalable PostgreSQL",
            features="High availability, automated backups, monitoring",
            is_featured=True,
        )
        self.postgresql_service.categories.add(self.database_category)

        # Create compute plan group
        self.standard_group = ComputePlanGroup.objects.create(
            name="Standard",
            description="Standard compute plans",
            node_label="standard",
            order=1,
        )

        # Create multiple compute plans
        self.small_plan = ComputePlan.objects.create(
            name="Small",
            vcpus=1.0,
            ram=2.0,
            cpu_mem_ratio=0.5,
            cloud_provider=self.cloud_provider,
            group=self.standard_group,
            term=Term.MTH,
            active=True,
        )

        self.medium_plan = ComputePlan.objects.create(
            name="Medium",
            vcpus=2.0,
            ram=4.0,
            cpu_mem_ratio=0.5,
            cloud_provider=self.cloud_provider,
            group=self.standard_group,
            term=Term.MTH,
            active=True,
        )

        self.large_plan = ComputePlan.objects.create(
            name="Large",
            vcpus=4.0,
            ram=8.0,
            cpu_mem_ratio=0.5,
            cloud_provider=self.cloud_provider,
            group=self.standard_group,
            term=Term.MTH,
            active=True,
        )

        # Create storage plan
        self.ssd_storage = StoragePlan.objects.create(
            name="SSD Storage",
            cloud_provider=self.cloud_provider,
            term=Term.MTH,
            unit=Unit.GIB,
        )

        # Create progressive discount model for AppCat
        self.ram_discount_model = ProgressiveDiscountModel.objects.create(
            name="RAM Volume Discount",
            description="Progressive discount for RAM usage",
            active=True,
        )

        # Create discount tiers
        DiscountTier.objects.create(
            discount_model=self.ram_discount_model,
            min_units=0,
            max_units=8,
            discount_percent=Decimal("0.00"),  # 0-7 GiB: no discount
        )

        DiscountTier.objects.create(
            discount_model=self.ram_discount_model,
            min_units=8,
            max_units=32,
            discount_percent=Decimal("10.00"),  # 8-31 GiB: 10% discount
        )

        DiscountTier.objects.create(
            discount_model=self.ram_discount_model,
            min_units=32,
            max_units=None,
            discount_percent=Decimal("20.00"),  # 32+ GiB: 20% discount
        )

    def test_complete_pricing_setup(self):
        """Test complete pricing setup for all models"""
        # Set up compute plan prices
        ComputePlanPrice.objects.create(
            compute_plan=self.small_plan, currency=Currency.CHF, amount=Decimal("50.00")
        )

        ComputePlanPrice.objects.create(
            compute_plan=self.medium_plan,
            currency=Currency.CHF,
            amount=Decimal("100.00"),
        )

        ComputePlanPrice.objects.create(
            compute_plan=self.large_plan,
            currency=Currency.CHF,
            amount=Decimal("200.00"),
        )

        # Set up storage pricing
        StoragePlanPrice.objects.create(
            storage_plan=self.ssd_storage,
            currency=Currency.CHF,
            amount=Decimal("0.20"),  # 0.20 CHF per GiB
        )

        # Verify all prices are retrievable
        self.assertEqual(self.small_plan.get_price(Currency.CHF), Decimal("50.00"))
        self.assertEqual(self.medium_plan.get_price(Currency.CHF), Decimal("100.00"))
        self.assertEqual(self.large_plan.get_price(Currency.CHF), Decimal("200.00"))
        self.assertEqual(self.ssd_storage.get_price(Currency.CHF), Decimal("0.20"))

    def test_multi_currency_pricing(self):
        """Test pricing in multiple currencies"""
        # Set up prices in CHF, EUR, and USD
        currencies_and_rates = [
            (Currency.CHF, Decimal("100.00")),
            (Currency.EUR, Decimal("95.00")),
            (Currency.USD, Decimal("110.00")),
        ]

        for currency, amount in currencies_and_rates:
            ComputePlanPrice.objects.create(
                compute_plan=self.medium_plan, currency=currency, amount=amount
            )

        # Verify all currencies are available
        for currency, expected_amount in currencies_and_rates:
            self.assertEqual(self.medium_plan.get_price(currency), expected_amount)

    def test_appcat_service_with_complete_pricing(self):
        """Test complete AppCat service pricing with all features"""
        # Create AppCat price configuration
        appcat_price = VSHNAppCatPrice.objects.create(
            service=self.postgresql_service,
            variable_unit=VSHNAppCatPrice.VariableUnit.RAM,
            term=Term.MTH,
            discount_model=self.ram_discount_model,
            ha_replica_min=1,
            ha_replica_max=3,
            public_display_enabled=True,
        )

        # Set up base fees for different currencies
        base_fees = [
            (Currency.CHF, Decimal("25.00")),
            (Currency.EUR, Decimal("22.50")),
            (Currency.USD, Decimal("27.50")),
        ]

        for currency, amount in base_fees:
            VSHNAppCatBaseFee.objects.create(
                vshn_appcat_price_config=appcat_price, currency=currency, service_level=VSHNAppCatPrice.ServiceLevel.GUARANTEED, amount=amount
            )

        # Set up unit rates for different service levels and currencies
        unit_rates = [
            (Currency.CHF, VSHNAppCatPrice.ServiceLevel.BEST_EFFORT, Decimal("3.5000")),
            (Currency.CHF, VSHNAppCatPrice.ServiceLevel.GUARANTEED, Decimal("5.0000")),
            (Currency.EUR, VSHNAppCatPrice.ServiceLevel.BEST_EFFORT, Decimal("3.2000")),
            (Currency.EUR, VSHNAppCatPrice.ServiceLevel.GUARANTEED, Decimal("4.5000")),
            (Currency.USD, VSHNAppCatPrice.ServiceLevel.BEST_EFFORT, Decimal("3.8000")),
            (Currency.USD, VSHNAppCatPrice.ServiceLevel.GUARANTEED, Decimal("5.5000")),
        ]

        for currency, service_level, amount in unit_rates:
            VSHNAppCatUnitRate.objects.create(
                vshn_appcat_price_config=appcat_price,
                currency=currency,
                service_level=service_level,
                amount=amount,
            )

        # Create mandatory addon (backup)
        backup_addon = VSHNAppCatAddon.objects.create(
            vshn_appcat_price_config=appcat_price,
            name="Automated Backup",
            description="Daily automated backups with 30-day retention",
            commercial_description="Never lose your data with automated daily backups",
            addon_type=VSHNAppCatAddon.AddonType.BASE_FEE,
            mandatory=True,
            order=1,
        )

        VSHNAppCatAddonBaseFee.objects.create(
            addon=backup_addon, currency=Currency.CHF, service_level=VSHNAppCatPrice.ServiceLevel.GUARANTEED, amount=Decimal("15.00")
        )

        # Create optional addon (monitoring)
        monitoring_addon = VSHNAppCatAddon.objects.create(
            vshn_appcat_price_config=appcat_price,
            name="Advanced Monitoring",
            description="Detailed monitoring with custom alerts",
            commercial_description="Get insights into your database performance",
            addon_type=VSHNAppCatAddon.AddonType.UNIT_RATE,
            mandatory=False,
            order=2,
        )

        VSHNAppCatAddonUnitRate.objects.create(
            addon=monitoring_addon,
            currency=Currency.CHF,
            service_level=VSHNAppCatPrice.ServiceLevel.GUARANTEED,
            amount=Decimal("0.5000"),
        )

        # Test price calculation scenarios

        # Scenario 1: Small setup (4 GiB RAM, no discount)
        result_small = appcat_price.calculate_final_price(
            Currency.CHF, VSHNAppCatPrice.ServiceLevel.GUARANTEED, 4
        )

        # Base: 25 + (5 * 4) = 45
        # Mandatory backup: 15
        # Total: 60
        self.assertEqual(result_small["total_price"], Decimal("60.00"))
        self.assertEqual(result_small["addon_total"], Decimal("15.00"))
        self.assertEqual(len(result_small["addon_breakdown"]), 1)

        # Scenario 2: Medium setup (16 GiB RAM, partial discount)
        result_medium = appcat_price.calculate_final_price(
            Currency.CHF, VSHNAppCatPrice.ServiceLevel.GUARANTEED, 16
        )

        # First 8 GiB at full rate: 5 * 8 = 40
        # Next 8 GiB at 90% (10% discount): 5 * 0.9 * 8 = 36
        # Unit cost: 76
        # Base: 25 + 76 = 101
        # Mandatory backup: 15
        # Total: 116
        self.assertEqual(result_medium["total_price"], Decimal("116.00"))

        # Scenario 3: Large setup with optional addon (40 GiB RAM, full discount tiers)
        result_large = appcat_price.calculate_final_price(
            Currency.CHF,
            VSHNAppCatPrice.ServiceLevel.GUARANTEED,
            40,
            addon_ids=[monitoring_addon.id],
        )

        # First 8 GiB at full rate: 5 * 8 = 40
        # Next 24 GiB at 90% (10% discount): 5 * 0.9 * 24 = 108
        # Next 8 GiB at 80% (20% discount): 5 * 0.8 * 8 = 32
        # Unit cost: 180
        # Base: 25 + 180 = 205
        # Mandatory backup: 15
        # Optional monitoring: 0.5 * 40 = 20
        # Total: 240
        self.assertEqual(result_large["total_price"], Decimal("240.00"))
        self.assertEqual(result_large["addon_total"], Decimal("35.00"))
        self.assertEqual(len(result_large["addon_breakdown"]), 2)

    def test_external_price_comparison_integration(self):
        """Test external price comparison with internal pricing"""
        # Set up internal pricing
        appcat_price = VSHNAppCatPrice.objects.create(
            service=self.postgresql_service,
            variable_unit=VSHNAppCatPrice.VariableUnit.RAM,
            term=Term.MTH,
        )

        VSHNAppCatBaseFee.objects.create(
            vshn_appcat_price_config=appcat_price,
            currency=Currency.USD,
            service_level=VSHNAppCatPrice.ServiceLevel.GUARANTEED,
            amount=Decimal("30.00"),
        )

        VSHNAppCatUnitRate.objects.create(
            vshn_appcat_price_config=appcat_price,
            currency=Currency.USD,
            service_level=VSHNAppCatPrice.ServiceLevel.GUARANTEED,
            amount=Decimal("4.0000"),
        )

        # Create external competitor pricing
        aws_provider = CloudProvider.objects.create(
            name="AWS",
            slug="aws",
            description="Amazon Web Services",
            website="https://aws.amazon.com",
        )

        external_price = ExternalPricePlans.objects.create(
            plan_name="RDS PostgreSQL db.t3.medium",
            description="AWS RDS PostgreSQL instance",
            source="https://aws.amazon.com/rds/postgresql/pricing/",
            cloud_provider=aws_provider,
            service=self.postgresql_service,
            vshn_appcat_price=appcat_price,
            service_level=VSHNAppCatPrice.ServiceLevel.GUARANTEED,
            currency=Currency.USD,
            term=Term.MTH,
            amount=Decimal("62.56"),  # Monthly cost for db.t3.medium
            vcpus=2.0,
            ram=4.0,  # 4 GiB RAM
            storage=20.0,  # 20 GiB storage included
            competitor_sla="99.95%",
            replicas=1,
        )

        # Compare internal vs external pricing for equivalent setup
        internal_result = appcat_price.calculate_final_price(
            Currency.USD,
            VSHNAppCatPrice.ServiceLevel.GUARANTEED,
            4,  # 4 GiB RAM to match external offering
        )

        # Internal: 30 + (4 * 4) = 46 USD
        internal_price = internal_result["total_price"]
        external_price_amount = external_price.amount

        self.assertEqual(internal_price, Decimal("46.00"))
        self.assertEqual(external_price_amount, Decimal("62.56"))

        # Verify our pricing is competitive
        self.assertLess(internal_price, external_price_amount)

    def test_service_availability_with_pricing(self):
        """Test service availability based on pricing configuration"""
        # Create service with pricing but not enabled for public display
        redis_service = Service.objects.create(
            name="Redis",
            slug="redis",
            description="In-memory data store",
            features="High performance caching",
        )

        redis_price = VSHNAppCatPrice.objects.create(
            service=redis_service,
            variable_unit=VSHNAppCatPrice.VariableUnit.RAM,
            term=Term.MTH,
            public_display_enabled=False,  # Private pricing
        )

        VSHNAppCatBaseFee.objects.create(
            vshn_appcat_price_config=redis_price,
            currency=Currency.CHF,
            service_level=VSHNAppCatPrice.ServiceLevel.GUARANTEED,
            amount=Decimal("20.00"),
        )

        # Service should exist but not be publicly available for pricing
        self.assertFalse(redis_price.public_display_enabled)

        # Enable public display
        redis_price.public_display_enabled = True
        redis_price.save()

        self.assertTrue(redis_price.public_display_enabled)

    def test_pricing_model_relationships(self):
        """Test all pricing model relationships work correctly"""
        # Verify cloud provider relationships
        self.assertEqual(self.cloud_provider.compute_plans.count(), 3)
        self.assertEqual(self.cloud_provider.storage_plans.count(), 1)

        # Verify service relationships
        self.assertTrue(hasattr(self.postgresql_service, "vshn_appcat_price"))

        # Verify compute plan group relationships
        self.assertEqual(self.standard_group.compute_plans.count(), 3)

        # Create and verify discount model relationships
        appcat_price = VSHNAppCatPrice.objects.create(
            service=self.postgresql_service,
            variable_unit=VSHNAppCatPrice.VariableUnit.RAM,
            term=Term.MTH,
            discount_model=self.ram_discount_model,
        )

        self.assertEqual(self.ram_discount_model.price_configs.count(), 1)
        self.assertEqual(self.ram_discount_model.tiers.count(), 3)

        # Test cascade deletions work properly
        service_id = self.postgresql_service.id
        appcat_price_id = appcat_price.id

        # Delete service should cascade to appcat price
        self.postgresql_service.delete()

        with self.assertRaises(VSHNAppCatPrice.DoesNotExist):
            VSHNAppCatPrice.objects.get(id=appcat_price_id)

    def test_comprehensive_pricing_scenario(self):
        """Test a comprehensive real-world pricing scenario"""
        # Company needs PostgreSQL with high availability
        # Requirements: 16 GiB RAM, automated backups, monitoring, SSL

        appcat_price = VSHNAppCatPrice.objects.create(
            service=self.postgresql_service,
            variable_unit=VSHNAppCatPrice.VariableUnit.RAM,
            term=Term.MTH,
            discount_model=self.ram_discount_model,
            ha_replica_min=2,
            ha_replica_max=3,
            public_display_enabled=True,
        )

        # Set up pricing
        VSHNAppCatBaseFee.objects.create(
            vshn_appcat_price_config=appcat_price,
            currency=Currency.CHF,
            service_level=VSHNAppCatPrice.ServiceLevel.GUARANTEED,
            amount=Decimal("40.00"),  # Base fee for managed service
        )

        VSHNAppCatUnitRate.objects.create(
            vshn_appcat_price_config=appcat_price,
            currency=Currency.CHF,
            service_level=VSHNAppCatPrice.ServiceLevel.GUARANTEED,
            amount=Decimal("6.0000"),  # CHF per GiB RAM
        )

        # Create all required addons
        backup_addon = VSHNAppCatAddon.objects.create(
            vshn_appcat_price_config=appcat_price,
            name="Enterprise Backup",
            addon_type=VSHNAppCatAddon.AddonType.BASE_FEE,
            mandatory=True,
            order=1,
        )

        VSHNAppCatAddonBaseFee.objects.create(
            addon=backup_addon, currency=Currency.CHF, service_level=VSHNAppCatPrice.ServiceLevel.GUARANTEED, amount=Decimal("25.00")
        )

        monitoring_addon = VSHNAppCatAddon.objects.create(
            vshn_appcat_price_config=appcat_price,
            name="Advanced Monitoring",
            addon_type=VSHNAppCatAddon.AddonType.UNIT_RATE,
            mandatory=False,
            order=2,
        )

        VSHNAppCatAddonUnitRate.objects.create(
            addon=monitoring_addon,
            currency=Currency.CHF,
            service_level=VSHNAppCatPrice.ServiceLevel.GUARANTEED,
            amount=Decimal("0.7500"),
        )

        ssl_addon = VSHNAppCatAddon.objects.create(
            vshn_appcat_price_config=appcat_price,
            name="SSL Certificate",
            addon_type=VSHNAppCatAddon.AddonType.BASE_FEE,
            mandatory=False,
            order=3,
        )

        VSHNAppCatAddonBaseFee.objects.create(
            addon=ssl_addon, currency=Currency.CHF, service_level=VSHNAppCatPrice.ServiceLevel.GUARANTEED, amount=Decimal("18.00")
        )

        # Calculate final price with all selected addons
        result = appcat_price.calculate_final_price(
            Currency.CHF,
            VSHNAppCatPrice.ServiceLevel.GUARANTEED,
            16,  # 16 GiB RAM
            addon_ids=[monitoring_addon.id, ssl_addon.id],
        )

        # Expected calculation:
        # Base fee: 40.00
        # RAM cost: First 8 at 6.00 = 48.00, Next 8 at 5.40 (10% discount) = 43.20
        # RAM total: 91.20
        # Mandatory backup: 25.00
        # Optional monitoring: 0.75 * 16 = 12.00
        # Optional SSL: 18.00
        # Total: 40.00 + 91.20 + 25.00 + 12.00 + 18.00 = 186.20

        self.assertEqual(result["total_price"], Decimal("186.20"))
        self.assertEqual(result["addon_total"], Decimal("55.00"))
        self.assertEqual(len(result["addon_breakdown"]), 3)

        # Verify addon breakdown details
        addon_names = [addon["name"] for addon in result["addon_breakdown"]]
        self.assertIn("Enterprise Backup", addon_names)
        self.assertIn("Advanced Monitoring", addon_names)
        self.assertIn("SSL Certificate", addon_names)
