"""
Test utilities and fixtures for pricing tests
"""

from decimal import Decimal
from django.test import TestCase

from ..models.base import Currency, Term, Unit
from ..models.providers import CloudProvider
from ..models.services import Service, Category
from ..models.pricing import (
    ProgressiveDiscountModel,
    DiscountTier,
    VSHNAppCatPrice,
    VSHNAppCatBaseFee,
    VSHNAppCatUnitRate,
)


class PricingTestMixin:
    """Mixin providing common setup for pricing tests"""

    def create_test_cloud_provider(self, name="Test Provider"):
        """Create a test cloud provider"""
        return CloudProvider.objects.create(
            name=name,
            slug=name.lower().replace(" ", "-"),
            description=f"{name} description",
            website=f"https://{name.lower().replace(' ', '')}.com",
        )

    def create_test_service(self, name="Test Service"):
        """Create a test service"""
        return Service.objects.create(
            name=name,
            slug=name.lower().replace(" ", "-"),
            description=f"{name} description",
            features=f"{name} features",
        )

    def create_test_discount_model(self, name="Test Discount", tiers=None):
        """Create a test discount model with optional tiers"""
        discount_model = ProgressiveDiscountModel.objects.create(
            name=name, description=f"{name} description", active=True
        )

        if tiers is None:
            # Default tiers: 0-9 (0%), 10-49 (10%), 50+ (20%)
            tiers = [
                (0, 10, Decimal("0.00")),
                (10, 50, Decimal("10.00")),
                (50, None, Decimal("20.00")),
            ]

        for min_units, max_units, discount_percent in tiers:
            DiscountTier.objects.create(
                discount_model=discount_model,
                min_units=min_units,
                max_units=max_units,
                discount_percent=discount_percent,
            )

        return discount_model

    def create_test_appcat_price(
        self,
        service,
        discount_model=None,
        base_fee=Decimal("50.00"),
        unit_rate=Decimal("5.0000"),
    ):
        """Create a test AppCat price configuration"""
        appcat_price = VSHNAppCatPrice.objects.create(
            service=service,
            variable_unit=VSHNAppCatPrice.VariableUnit.RAM,
            term=Term.MTH,
            discount_model=discount_model,
        )

        # Create base fee
        VSHNAppCatBaseFee.objects.create(
            vshn_appcat_price_config=appcat_price,
            currency=Currency.CHF,
            service_level=VSHNAppCatPrice.ServiceLevel.GUARANTEED,
            amount=base_fee,
        )

        # Create unit rate
        VSHNAppCatUnitRate.objects.create(
            vshn_appcat_price_config=appcat_price,
            currency=Currency.CHF,
            service_level=VSHNAppCatPrice.ServiceLevel.GUARANTEED,
            amount=unit_rate,
        )

        return appcat_price


def calculate_expected_discounted_price(base_rate, units, discount_tiers):
    """Helper function to calculate expected discounted price manually"""
    final_price = Decimal("0")
    remaining_units = units

    # Sort tiers by min_units
    sorted_tiers = sorted(discount_tiers, key=lambda x: x[0])

    for min_units, max_units, discount_percent in sorted_tiers:
        if remaining_units <= 0:
            break

        # Skip if we haven't reached this tier yet
        if units < min_units:
            continue

        # Calculate units in this tier
        tier_max = max_units if max_units else float("inf")
        units_start = max(0, units - remaining_units)
        units_end = min(units, tier_max if max_units else units)
        tier_units = max(0, units_end - max(units_start, min_units - 1))

        if tier_units > 0:
            discounted_rate = base_rate * (1 - discount_percent / 100)
            final_price += discounted_rate * tier_units
            remaining_units -= tier_units

    return final_price
