"""
Coupon system for subscription discounts and promotions.
Supports trial extensions, percentage discounts, and fixed amount discounts.
"""
from dataclasses import dataclass
from datetime import datetime, timezone
from enum import Enum
from typing import Optional


class DiscountType(str, Enum):
    """Type of discount offered by a coupon"""
    TRIAL_EXTENSION = "trial_extension"  # Extends trial period by X days
    PERCENTAGE = "percentage"  # X% off subscription price
    FIXED_AMOUNT = "fixed_amount"  # Fixed amount off subscription price


@dataclass
class Coupon:
    """Coupon configuration"""
    id: str
    code: str
    discount_type: DiscountType
    discount_value: int  # Days for trial_extension, percentage for percentage, cents for fixed_amount
    max_redemptions: Optional[int]  # None = unlimited
    current_redemptions: int
    valid_from: datetime
    valid_until: Optional[datetime]  # None = no expiry
    active: bool
    created_at: datetime
    extra_data: Optional[dict] = None

    def is_valid(self) -> bool:
        """Check if coupon is currently valid"""
        now = datetime.now(timezone.utc)

        # Check if active
        if not self.active:
            return False

        # Check if started
        if now < self.valid_from:
            return False

        # Check if expired
        if self.valid_until and now > self.valid_until:
            return False

        # Check if max redemptions reached
        if self.max_redemptions and self.current_redemptions >= self.max_redemptions:
            return False

        return True

    def can_be_redeemed(self) -> tuple[bool, str]:
        """
        Check if coupon can be redeemed.
        Returns (can_redeem, reason_if_not)
        """
        if not self.active:
            return False, "Coupon is inactive"

        now = datetime.now(timezone.utc)

        if now < self.valid_from:
            return False, "Coupon is not yet valid"

        if self.valid_until and now > self.valid_until:
            return False, "Coupon has expired"

        if self.max_redemptions and self.current_redemptions >= self.max_redemptions:
            return False, "Coupon has reached maximum redemptions"

        return True, ""


@dataclass
class CouponRedemption:
    """Record of a coupon redemption"""
    id: str
    tenant_id: str
    coupon_code: str
    redeemed_at: datetime
    discount_applied: dict  # Details of the discount applied
    extra_data: Optional[dict] = None


@dataclass
class CouponValidationResult:
    """Result of coupon validation"""
    valid: bool
    coupon: Optional[Coupon]
    error_message: Optional[str]
    discount_preview: Optional[dict]  # Preview of discount to be applied


def calculate_trial_end_date(base_trial_days: int, extension_days: int) -> datetime:
    """Calculate trial end date with coupon extension"""
    from datetime import timedelta
    total_days = base_trial_days + extension_days
    return datetime.now(timezone.utc) + timedelta(days=total_days)


def format_discount_description(coupon: Coupon) -> str:
    """Format human-readable discount description"""
    if coupon.discount_type == DiscountType.TRIAL_EXTENSION:
        months = coupon.discount_value // 30
        days = coupon.discount_value % 30
        if months > 0 and days == 0:
            return f"{months} {'mes' if months == 1 else 'meses'} gratis"
        elif months > 0:
            return f"{months} {'mes' if months == 1 else 'meses'} y {days} días gratis"
        else:
            return f"{coupon.discount_value} días gratis"

    elif coupon.discount_type == DiscountType.PERCENTAGE:
        return f"{coupon.discount_value}% de descuento"

    elif coupon.discount_type == DiscountType.FIXED_AMOUNT:
        amount = coupon.discount_value / 100  # Convert cents to euros
        return f"€{amount:.2f} de descuento"

    return "Descuento aplicado"
