from __future__ import annotations

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

from pydantic import BaseModel, ConfigDict, Field


class CommercialBillingPeriodRead(BaseModel):
    model_config = ConfigDict(from_attributes=True)

    id: str
    tenant_id: str
    subscription_id: str
    plan_id: str
    period_sequence: int
    period_key: str
    status: Literal["issued"]
    temporal_state: Literal["upcoming", "current", "elapsed"]
    period_start: datetime
    period_end: datetime
    subscription_status_snapshot: Literal[
        "trialing",
        "active",
        "past_due",
        "suspended",
        "canceled",
        "expired",
    ]
    plan_code_snapshot: str
    plan_version_snapshot: int
    pricing_model_snapshot: Literal[
        "subscription",
        "usage",
        "hybrid",
        "pilot",
        "custom",
    ]
    billing_interval: Literal["monthly", "quarterly", "annual", "contract"]
    currency: str
    base_fee_snapshot: Decimal
    seats_snapshot: int
    source: Literal["subscription_created", "auto_renew", "migration_backfill"]
    idempotency_key: str
    created_by: str
    created_at: datetime


class CommercialBillingPeriodTenantRead(BaseModel):
    """租户可见账期，不暴露平台操作人和内部幂等键。"""

    model_config = ConfigDict(from_attributes=True)

    id: str
    tenant_id: str
    subscription_id: str
    plan_id: str
    period_sequence: int
    period_key: str
    status: Literal["issued"]
    temporal_state: Literal["upcoming", "current", "elapsed"]
    period_start: datetime
    period_end: datetime
    subscription_status_snapshot: str
    plan_code_snapshot: str
    plan_version_snapshot: int
    pricing_model_snapshot: str
    billing_interval: str
    currency: str
    base_fee_snapshot: Decimal
    seats_snapshot: int
    source: str
    created_at: datetime


class CommercialAdminEventRead(BaseModel):
    model_config = ConfigDict(from_attributes=True)

    id: str
    tenant_id: str
    actor_type: Literal["user", "system", "migration"]
    actor_id: str
    request_id: str
    reason: str
    action: Literal[
        "plan_created",
        "plan_activated",
        "plan_retired",
        "subscription_created",
        "subscription_activated",
        "subscription_transitioned",
        "entitlement_created",
        "entitlement_updated",
        "entitlement_activated",
        "billing_period_created",
        "subscription_rolled_over",
        "legacy_state_imported",
    ]
    resource_type: Literal["plan", "subscription", "entitlement", "billing_period"]
    resource_id: str
    resource_version: int
    before_json: dict[str, Any] = Field(default_factory=dict)
    after_json: dict[str, Any] = Field(default_factory=dict)
    occurred_at: datetime


class CommercialRolloverRead(BaseModel):
    tenant_id: str
    subscription_id: str
    status: Literal["rolled_over", "not_due", "ineligible", "replayed"]
    reason_code: str
    reason: str
    created_period_ids: list[str] = Field(default_factory=list)
    current_period_start: datetime
    current_period_end: datetime
    subscription_version: int
