"""
Pydantic schemas for core.billing.

These schemas validate JSONFields in Django models and provide typed
interfaces for Stripe metadata.
"""

from __future__ import annotations

from typing import Literal

from pydantic import BaseModel, ConfigDict, Field

# =============================================================================
# Stripe Product Metadata Schema
# =============================================================================


class ProductMetadataSchema(BaseModel):
    """
    Typed metadata for Stripe products.

    This schema defines the structure of metadata we store on Stripe products.
    Products should be configured in Stripe with these metadata fields.
    """

    model_config = ConfigDict(
        extra="allow",  # Allow extra fields from Stripe
        populate_by_name=True,
    )

    # Product tier mapping
    tier: Literal["free", "starter", "pro", "enterprise"] | None = Field(
        default=None,
        description="Internal subscription tier this product maps to",
    )

    # Domain access
    domain_access: list[str] | None = Field(
        default=None,
        description="List of domain slugs this product grants access to",
    )
    is_full_access: bool = Field(
        default=False,
        description="Whether this product grants full CreateOS access",
    )

    # Feature flags
    features: list[str] | None = Field(
        default=None,
        description="List of feature flags enabled by this product",
    )

    # Display properties
    display_order: int | None = Field(
        default=None,
        description="Order for display in pricing tables",
    )
    is_featured: bool = Field(
        default=False,
        description="Whether to highlight this product",
    )


class PriceMetadataSchema(BaseModel):
    """
    Typed metadata for Stripe prices.

    This schema defines the structure of metadata we store on Stripe prices.
    """

    model_config = ConfigDict(
        extra="allow",  # Allow extra fields from Stripe
        populate_by_name=True,
    )

    # Lookup key for programmatic access
    lookup_key: str | None = Field(
        default=None,
        description="Unique key for looking up this price programmatically",
    )

    # Billing interval display
    interval_display: str | None = Field(
        default=None,
        description="Human-readable billing interval (e.g., '/month')",
    )


# =============================================================================
# Subscription Schemas
# =============================================================================


class SubscriptionSchema(BaseModel):
    """Schema for Subscription data."""

    model_config = ConfigDict(
        extra="forbid",
        populate_by_name=True,
    )

    tier: Literal["free", "starter", "pro", "enterprise"] = Field(
        description="Subscription tier level",
    )
    status: Literal["active", "past_due", "canceled", "trialing", "incomplete"] = Field(
        description="Current subscription status",
    )
    stripe_subscription_id: str | None = Field(
        default=None,
        description="Stripe subscription ID",
    )
    stripe_customer_id: str | None = Field(
        default=None,
        description="Stripe customer ID",
    )
    current_period_start: str | None = Field(
        default=None,
        description="ISO timestamp of current period start",
    )
    current_period_end: str | None = Field(
        default=None,
        description="ISO timestamp of current period end",
    )
    cancel_at_period_end: bool = Field(
        default=False,
        description="Whether subscription will cancel at period end",
    )


class DomainSubscriptionSchema(BaseModel):
    """Schema for DomainSubscription data."""

    model_config = ConfigDict(
        extra="forbid",
        populate_by_name=True,
    )

    domain_name: str = Field(
        description="Domain this subscription grants access to",
    )
    tier: Literal["free", "starter", "pro", "enterprise"] = Field(
        description="Subscription tier level",
    )
    is_full_access: bool = Field(
        default=False,
        description="Whether this grants access to all domains",
    )
    is_active: bool = Field(
        default=True,
        description="Whether subscription is currently active",
    )


# =============================================================================
# Billing Settings Schema
# =============================================================================


class BillingSettingsSchema(BaseModel):
    """
    Schema for tenant billing settings.

    Stored in TenantBilling.settings JSONField.
    """

    model_config = ConfigDict(
        extra="forbid",
        populate_by_name=True,
    )

    # Tax settings
    tax_exempt: bool = Field(
        default=False,
        description="Whether tenant is tax exempt",
    )
    tax_id: str | None = Field(
        default=None,
        description="Tax ID for invoicing",
    )

    # Invoice settings
    invoice_prefix: str | None = Field(
        default=None,
        description="Custom prefix for invoice numbers",
    )
    send_invoice_emails: bool = Field(
        default=True,
        description="Whether to send invoice emails",
    )

    # Payment settings
    default_payment_method_id: str | None = Field(
        default=None,
        description="Default Stripe payment method ID",
    )

    # Feature flags from subscription
    enabled_features: list[str] = Field(
        default_factory=list,
        description="Features enabled by current subscription",
    )


# =============================================================================
# Exports
# =============================================================================

__all__ = [
    "ProductMetadataSchema",
    "PriceMetadataSchema",
    "SubscriptionSchema",
    "DomainSubscriptionSchema",
    "BillingSettingsSchema",
]
