"""Subscription models."""

from datetime import datetime
from enum import Enum
from typing import Any
from uuid import UUID

from pydantic import BaseModel, Field


class SubscriptionStatus(str, Enum):
    """Subscription status values."""

    TRIALING = "trialing"
    ACTIVE = "active"
    PAST_DUE = "past_due"
    CANCELED = "canceled"
    UNPAID = "unpaid"
    PAUSED = "paused"


class BillingCycle(str, Enum):
    """Billing cycle options."""

    MONTHLY = "monthly"
    YEARLY = "yearly"


class Subscription(BaseModel):
    """Active subscription."""

    id: UUID | None = Field(default=None, description="Subscription ID")
    subscriber_id: UUID | None = Field(default=None, description="Subscriber ID")
    subscriber_external_id: str | None = Field(default=None, description="External subscriber ID")
    plan_id: UUID | None = Field(default=None, description="Plan ID")
    plan_slug: str | None = Field(default=None, description="Plan slug")
    plan_name: str | None = Field(default=None, description="Plan name")
    stripe_subscription_id: str | None = Field(default=None, description="Stripe subscription ID")
    status: SubscriptionStatus = Field(..., description="Subscription status")
    billing_cycle: BillingCycle = Field(default=BillingCycle.MONTHLY, description="Billing cycle")
    current_period_start: datetime | None = Field(default=None, description="Period start")
    current_period_end: datetime | None = Field(default=None, description="Period end")
    trial_start: datetime | None = Field(default=None, description="Trial start")
    trial_end: datetime | None = Field(default=None, description="Trial end")
    canceled_at: datetime | None = Field(default=None, description="Cancellation timestamp")
    cancel_at: datetime | None = Field(default=None, description="Scheduled cancellation")
    paused_at: datetime | None = Field(default=None, description="Pause timestamp")
    custom_data: dict[str, Any] | None = Field(default=None, description="Custom metadata")
    created_at: datetime | None = Field(default=None, description="Creation timestamp")
    updated_at: datetime | None = Field(default=None, description="Last update timestamp")

    @property
    def is_active(self) -> bool:
        """Check if subscription is currently active."""
        return self.status in (SubscriptionStatus.ACTIVE, SubscriptionStatus.TRIALING)

    @property
    def is_trialing(self) -> bool:
        """Check if subscription is in trial period."""
        return self.status == SubscriptionStatus.TRIALING

    @property
    def will_cancel(self) -> bool:
        """Check if subscription is scheduled to cancel."""
        return self.cancel_at is not None

    @property
    def trial_days_remaining(self) -> int | None:
        """Calculate remaining trial days."""
        if not self.is_trialing or not self.trial_end:
            return None
        delta = self.trial_end - datetime.now(self.trial_end.tzinfo)
        return max(0, delta.days)

    @property
    def days_until_renewal(self) -> int | None:
        """Calculate days until next renewal."""
        if not self.current_period_end:
            return None
        delta = self.current_period_end - datetime.now(self.current_period_end.tzinfo)
        return max(0, delta.days)

    class Config:
        from_attributes = True
