"""
Unit тесты для моделей подписок.
"""
import pytest
from django.utils import timezone
from datetime import timedelta
from decimal import Decimal
from apps.subscriptions.models import (
    SubscriptionPlan, DurationDiscount, BulkDiscount,
    Subscription, Payment, PromoCode
)


@pytest.mark.django_db
@pytest.mark.unit
class TestSubscriptionPlanModel:
    """Тесты модели SubscriptionPlan."""
    
    def test_create_plan(self):
        """Тест создания тарифного плана."""
        plan = SubscriptionPlan.objects.create(
            name='Базовый',
            slug='basic',
            description='Базовый тариф',
            price=Decimal('1000.00'),
            duration_days=30,
            max_students=5,
            is_active=True
        )
        
        assert plan.name == 'Базовый'
        assert plan.slug == 'basic'
        assert plan.price == Decimal('1000.00')
        assert plan.duration_days == 30
        assert plan.max_students == 5
        assert plan.is_active is True
    
    def test_plan_str(self):
        """Тест строкового представления плана."""
        plan = SubscriptionPlan.objects.create(
            name='Премиум',
            slug='premium',
            price=Decimal('2000.00'),
            duration_days=30
        )
        
        assert 'Премиум' in str(plan)


@pytest.mark.django_db
@pytest.mark.unit
class TestDurationDiscountModel:
    """Тесты модели DurationDiscount."""
    
    def test_create_duration_discount(self):
        """Тест создания скидки за длительность."""
        plan = SubscriptionPlan.objects.create(
            name='Базовый',
            slug='basic',
            price=Decimal('1000.00'),
            duration_days=30
        )
        
        discount = DurationDiscount.objects.create(
            plan=plan,
            duration_days=90,
            discount_percent=10
        )
        
        assert discount.plan == plan
        assert discount.duration_days == 90
        assert discount.discount_percent == 10


@pytest.mark.django_db
@pytest.mark.unit
class TestSubscriptionModel:
    """Тесты модели Subscription."""
    
    def test_create_subscription(self, mentor_user):
        """Тест создания подписки."""
        plan = SubscriptionPlan.objects.create(
            name='Базовый',
            slug='basic',
            price=Decimal('1000.00'),
            duration_days=30
        )
        
        subscription = Subscription.objects.create(
            user=mentor_user,
            plan=plan,
            status='active',
            start_date=timezone.now().date(),
            end_date=(timezone.now() + timedelta(days=30)).date()
        )
        
        assert subscription.user == mentor_user
        assert subscription.plan == plan
        assert subscription.status == 'active'
    
    def test_subscription_is_active(self, mentor_user):
        """Тест проверки активности подписки."""
        plan = SubscriptionPlan.objects.create(
            name='Базовый',
            slug='basic',
            price=Decimal('1000.00'),
            duration_days=30
        )
        
        # Активная подписка
        active_sub = Subscription.objects.create(
            user=mentor_user,
            plan=plan,
            status='active',
            start_date=timezone.now().date(),
            end_date=(timezone.now() + timedelta(days=10)).date()
        )
        
        assert active_sub.is_active() is True
        
        # Истекшая подписка
        expired_sub = Subscription.objects.create(
            user=mentor_user,
            plan=plan,
            status='expired',
            start_date=(timezone.now() - timedelta(days=40)).date(),
            end_date=(timezone.now() - timedelta(days=10)).date()
        )
        
        assert expired_sub.is_active() is False


@pytest.mark.django_db
@pytest.mark.unit
class TestPromoCodeModel:
    """Тесты модели PromoCode."""
    
    def test_create_promo_code(self):
        """Тест создания промокода."""
        promo = PromoCode.objects.create(
            code='SUMMER2024',
            discount_percent=20,
            max_uses=100,
            is_active=True
        )
        
        assert promo.code == 'SUMMER2024'
        assert promo.discount_percent == 20
        assert promo.max_uses == 100
        assert promo.is_active is True
    
    def test_promo_code_is_valid(self):
        """Тест проверки валидности промокода."""
        # Валидный промокод
        valid_promo = PromoCode.objects.create(
            code='VALID',
            discount_percent=10,
            max_uses=100,
            is_active=True
        )
        
        assert valid_promo.is_valid() is True
        
        # Неактивный промокод
        inactive_promo = PromoCode.objects.create(
            code='INACTIVE',
            discount_percent=10,
            is_active=False
        )
        
        assert inactive_promo.is_valid() is False

