# app/modules/billing/schemas/billing.py
"""
Pydantic schemas for billing and subscription operations.

Used for both vendor billing endpoints and admin subscription management.
"""

from datetime import datetime

from pydantic import BaseModel, ConfigDict, Field


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


class SubscriptionTierBase(BaseModel):
    """Base schema for subscription tier."""

    code: str = Field(..., min_length=1, max_length=30)
    name: str = Field(..., min_length=1, max_length=100)
    description: str | None = None
    price_monthly_cents: int = Field(..., ge=0)
    price_annual_cents: int | None = Field(None, ge=0)
    orders_per_month: int | None = Field(None, ge=0)
    products_limit: int | None = Field(None, ge=0)
    team_members: int | None = Field(None, ge=0)
    order_history_months: int | None = Field(None, ge=0)
    features: list[str] = Field(default_factory=list)
    stripe_product_id: str | None = None
    stripe_price_monthly_id: str | None = None
    stripe_price_annual_id: str | None = None
    display_order: int = 0
    is_active: bool = True
    is_public: bool = True


class SubscriptionTierCreate(SubscriptionTierBase):
    """Schema for creating a subscription tier."""

    pass


class SubscriptionTierUpdate(BaseModel):
    """Schema for updating a subscription tier."""

    name: str | None = None
    description: str | None = None
    price_monthly_cents: int | None = Field(None, ge=0)
    price_annual_cents: int | None = Field(None, ge=0)
    orders_per_month: int | None = None
    products_limit: int | None = None
    team_members: int | None = None
    order_history_months: int | None = None
    features: list[str] | None = None
    stripe_product_id: str | None = None
    stripe_price_monthly_id: str | None = None
    stripe_price_annual_id: str | None = None
    display_order: int | None = None
    is_active: bool | None = None
    is_public: bool | None = None


class SubscriptionTierResponse(SubscriptionTierBase):
    """Schema for subscription tier response."""

    model_config = ConfigDict(from_attributes=True)

    id: int
    created_at: datetime
    updated_at: datetime

    # Computed fields for display
    @property
    def price_monthly_display(self) -> str:
        """Format monthly price for display."""
        return f"€{self.price_monthly_cents / 100:.2f}"

    @property
    def price_annual_display(self) -> str | None:
        """Format annual price for display."""
        if self.price_annual_cents is None:
            return None
        return f"€{self.price_annual_cents / 100:.2f}"


class SubscriptionTierListResponse(BaseModel):
    """Response for listing subscription tiers."""

    tiers: list[SubscriptionTierResponse]
    total: int


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


class VendorSubscriptionResponse(BaseModel):
    """Schema for vendor subscription response."""

    model_config = ConfigDict(from_attributes=True)

    id: int
    vendor_id: int
    tier: str
    status: str

    # Period info
    period_start: datetime
    period_end: datetime
    is_annual: bool
    trial_ends_at: datetime | None = None

    # Usage
    orders_this_period: int
    orders_limit_reached_at: datetime | None = None

    # Limits (effective)
    orders_limit: int | None = None
    products_limit: int | None = None
    team_members_limit: int | None = None

    # Custom overrides
    custom_orders_limit: int | None = None
    custom_products_limit: int | None = None
    custom_team_limit: int | None = None

    # Stripe
    stripe_customer_id: str | None = None
    stripe_subscription_id: str | None = None

    # Cancellation
    cancelled_at: datetime | None = None
    cancellation_reason: str | None = None

    # Timestamps
    created_at: datetime
    updated_at: datetime


class VendorSubscriptionWithVendor(VendorSubscriptionResponse):
    """Subscription response with vendor info."""

    vendor_name: str
    vendor_code: str

    # Usage counts (for admin display)
    products_count: int | None = None
    team_count: int | None = None


class VendorSubscriptionListResponse(BaseModel):
    """Response for listing vendor subscriptions."""

    subscriptions: list[VendorSubscriptionWithVendor]
    total: int
    page: int
    per_page: int
    pages: int


class VendorSubscriptionCreate(BaseModel):
    """Schema for admin creating a vendor subscription."""

    tier: str = "essential"
    status: str = "trial"
    trial_days: int = 14
    is_annual: bool = False


class VendorSubscriptionUpdate(BaseModel):
    """Schema for admin updating a vendor subscription."""

    tier: str | None = None
    status: str | None = None
    custom_orders_limit: int | None = None
    custom_products_limit: int | None = None
    custom_team_limit: int | None = None
    trial_ends_at: datetime | None = None
    cancellation_reason: str | None = None


# ============================================================================
# Billing History Schemas
# ============================================================================


class BillingHistoryResponse(BaseModel):
    """Schema for billing history entry."""

    model_config = ConfigDict(from_attributes=True)

    id: int
    vendor_id: int
    stripe_invoice_id: str | None = None
    invoice_number: str | None = None
    invoice_date: datetime
    due_date: datetime | None = None

    # Amounts
    subtotal_cents: int
    tax_cents: int
    total_cents: int
    amount_paid_cents: int
    currency: str = "EUR"

    # Status
    status: str

    # URLs
    invoice_pdf_url: str | None = None
    hosted_invoice_url: str | None = None

    # Description
    description: str | None = None

    # Timestamps
    created_at: datetime

    @property
    def total_display(self) -> str:
        """Format total for display."""
        return f"€{self.total_cents / 100:.2f}"


class BillingHistoryWithVendor(BillingHistoryResponse):
    """Billing history with vendor info."""

    vendor_name: str
    vendor_code: str


class BillingHistoryListResponse(BaseModel):
    """Response for listing billing history."""

    invoices: list[BillingHistoryWithVendor]
    total: int
    page: int
    per_page: int
    pages: int


# ============================================================================
# Checkout & Portal Schemas
# ============================================================================


class CheckoutRequest(BaseModel):
    """Request for creating checkout session."""

    tier_code: str
    is_annual: bool = False


class CheckoutResponse(BaseModel):
    """Response with checkout session URL."""

    checkout_url: str
    session_id: str


class PortalSessionResponse(BaseModel):
    """Response with customer portal URL."""

    portal_url: str


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


class SubscriptionStatsResponse(BaseModel):
    """Subscription statistics for admin dashboard."""

    total_subscriptions: int
    active_count: int
    trial_count: int
    past_due_count: int
    cancelled_count: int
    expired_count: int

    # By tier
    tier_distribution: dict[str, int]

    # Revenue
    mrr_cents: int  # Monthly recurring revenue
    arr_cents: int  # Annual recurring revenue

    @property
    def mrr_display(self) -> str:
        """Format MRR for display."""
        return f"€{self.mrr_cents / 100:,.2f}"

    @property
    def arr_display(self) -> str:
        """Format ARR for display."""
        return f"€{self.arr_cents / 100:,.2f}"
