"""Plan models."""

from datetime import datetime
from decimal import Decimal
from typing import Any, Literal
from uuid import UUID

from pydantic import BaseModel, Field

PricingModel = Literal["free", "flat", "usage", "hybrid", "commission"]


class PlanLimits(BaseModel):
    """Plan usage limits."""

    conversations: int | None = Field(default=None, description="Max conversations per month")
    stores: int | None = Field(default=None, description="Max connected stores")
    chatbots: int | None = Field(default=None, description="Max chatbots")
    datastores: int | None = Field(default=None, description="Max datastores")
    api_calls: int | None = Field(default=None, description="Max API calls per month")
    storage_gb: int | None = Field(default=None, description="Max storage in GB")

    class Config:
        extra = "allow"  # Allow additional limit fields


class Plan(BaseModel):
    """Subscription plan."""

    id: UUID | None = Field(default=None, description="GrowFlow internal plan ID")
    slug: str = Field(..., description="Unique plan identifier")
    name: str = Field(..., description="Display name")
    description: str | None = Field(default=None, description="Plan description")
    pricing_model: PricingModel = Field(default="flat", description="Pricing model type")
    price_monthly: Decimal | None = Field(default=None, description="Monthly price")
    price_yearly: Decimal | None = Field(default=None, description="Yearly price")
    currency: str = Field(default="EUR", description="Currency code (ISO 4217)")
    limits: dict[str, Any] | None = Field(default=None, description="Usage limits")
    features: list[str] | None = Field(default=None, description="Feature list")
    trial_days: int = Field(default=14, description="Trial period in days")
    contact_sales: bool = Field(default=False, description="Requires sales contact")
    sort_order: int = Field(default=0, description="Display order")
    color: str = Field(default="gray", description="Plan badge color")
    is_active: bool = Field(default=True, description="Whether plan is visible")
    commission_percent: Decimal | None = Field(
        default=None, description="Commission percentage (for reseller models)",
    )
    created_at: datetime | None = Field(default=None, description="Creation timestamp")
    updated_at: datetime | None = Field(default=None, description="Last update timestamp")

    @property
    def plan_limits(self) -> PlanLimits:
        """Get limits as PlanLimits object."""
        if self.limits:
            return PlanLimits(**self.limits)
        return PlanLimits()

    @property
    def is_free(self) -> bool:
        """Check if this is a free plan."""
        return (self.price_monthly is None or self.price_monthly == 0) and (
            self.price_yearly is None or self.price_yearly == 0
        )

    @property
    def is_enterprise(self) -> bool:
        """Check if this is an enterprise/contact sales plan."""
        return self.contact_sales

    def get_price(self, billing_cycle: str = "monthly") -> Decimal | None:
        """Get price for billing cycle."""
        if billing_cycle == "yearly":
            return self.price_yearly
        return self.price_monthly

    def get(self, key: str, default: Any = None) -> Any:
        """Get attribute by key (dict-like access for backwards compatibility).

        This allows using Plan objects like dictionaries:
            plan.get("slug")  # Works like plan.slug
            plan.get("missing", "default")  # Returns "default"
        """
        return getattr(self, key, default)

    def __getitem__(self, key: str) -> Any:
        """Get attribute by key (dict-like access for backwards compatibility).

        This allows using Plan objects like dictionaries:
            plan["slug"]  # Works like plan.slug
        """
        if hasattr(self, key):
            return getattr(self, key)
        raise KeyError(key)

    class Config:
        from_attributes = True
