"""Membership Catalog schemas — Phase 9.1."""
from __future__ import annotations

from datetime import date, datetime
from decimal import Decimal
from uuid import UUID

from pydantic import BaseModel, Field

from app.models.types import BillingPeriod, LifecycleStatus, PricingModelKind, RuleKind
from app.schemas.common import ORMBase


class SportCategoryCreate(BaseModel):
    sports_center_id: UUID
    code: str = Field(max_length=50)
    name: str = Field(max_length=255)
    description: str | None = None
    status: LifecycleStatus = LifecycleStatus.ACTIVE
    sort_order: int = 0
    attributes: dict | None = None


class SportCategoryUpdate(BaseModel):
    name: str | None = Field(default=None, max_length=255)
    description: str | None = None
    status: LifecycleStatus | None = None
    sort_order: int | None = None
    attributes: dict | None = None


class SportCategoryRead(ORMBase):
    id: UUID
    tenant_id: UUID
    sports_center_id: UUID
    code: str
    name: str
    description: str | None
    status: LifecycleStatus
    sort_order: int
    attributes: dict | None
    is_deleted: bool
    created_at: datetime
    updated_at: datetime


class AgeGroupCreate(BaseModel):
    sports_center_id: UUID
    code: str = Field(max_length=50)
    name: str = Field(max_length=255)
    description: str | None = None
    status: LifecycleStatus = LifecycleStatus.ACTIVE
    min_age: int | None = None
    max_age: int | None = None
    sort_order: int = 0


class AgeGroupUpdate(BaseModel):
    name: str | None = Field(default=None, max_length=255)
    description: str | None = None
    status: LifecycleStatus | None = None
    min_age: int | None = None
    max_age: int | None = None
    sort_order: int | None = None


class AgeGroupRead(ORMBase):
    id: UUID
    tenant_id: UUID
    sports_center_id: UUID
    code: str
    name: str
    description: str | None
    status: LifecycleStatus
    min_age: int | None
    max_age: int | None
    sort_order: int
    is_deleted: bool
    created_at: datetime
    updated_at: datetime


class PricingModelCreate(BaseModel):
    sports_center_id: UUID
    code: str = Field(max_length=50)
    name: str = Field(max_length=255)
    description: str | None = None
    status: LifecycleStatus = LifecycleStatus.ACTIVE
    kind: PricingModelKind = PricingModelKind.FIXED
    billing_period: BillingPeriod = BillingPeriod.MONTHLY
    currency_code: str = Field(default="IRR", max_length=3)
    amount: Decimal | None = None
    tiers: list | None = None
    tax_inclusive: bool = True
    external_price_ref: str | None = Field(default=None, max_length=100)
    metadata_json: dict | None = None


class PricingModelUpdate(BaseModel):
    name: str | None = Field(default=None, max_length=255)
    description: str | None = None
    status: LifecycleStatus | None = None
    kind: PricingModelKind | None = None
    billing_period: BillingPeriod | None = None
    currency_code: str | None = Field(default=None, max_length=3)
    amount: Decimal | None = None
    tiers: list | None = None
    tax_inclusive: bool | None = None
    external_price_ref: str | None = Field(default=None, max_length=100)
    metadata_json: dict | None = None


class PricingModelRead(ORMBase):
    id: UUID
    tenant_id: UUID
    sports_center_id: UUID
    code: str
    name: str
    description: str | None
    status: LifecycleStatus
    kind: PricingModelKind
    billing_period: BillingPeriod
    currency_code: str
    amount: Decimal | None
    tiers: list | None
    tax_inclusive: bool
    external_price_ref: str | None
    metadata_json: dict | None
    is_deleted: bool
    created_at: datetime
    updated_at: datetime


class MembershipPackageCreate(BaseModel):
    sports_center_id: UUID
    code: str = Field(max_length=50)
    name: str = Field(max_length=255)
    description: str | None = None
    status: LifecycleStatus = LifecycleStatus.ACTIVE
    pricing_model_id: UUID | None = None
    sport_ids: list | None = None
    included_items: dict | None = None
    session_credits: int | None = None
    valid_from: date | None = None
    valid_until: date | None = None
    metadata_json: dict | None = None


class MembershipPackageUpdate(BaseModel):
    name: str | None = Field(default=None, max_length=255)
    description: str | None = None
    status: LifecycleStatus | None = None
    pricing_model_id: UUID | None = None
    sport_ids: list | None = None
    included_items: dict | None = None
    session_credits: int | None = None
    valid_from: date | None = None
    valid_until: date | None = None
    metadata_json: dict | None = None


class MembershipPackageRead(ORMBase):
    id: UUID
    tenant_id: UUID
    sports_center_id: UUID
    code: str
    name: str
    description: str | None
    status: LifecycleStatus
    pricing_model_id: UUID | None
    sport_ids: list | None
    included_items: dict | None
    session_credits: int | None
    valid_from: date | None
    valid_until: date | None
    metadata_json: dict | None
    is_deleted: bool
    created_at: datetime
    updated_at: datetime


class MembershipPlanCreate(BaseModel):
    sports_center_id: UUID
    code: str = Field(max_length=50)
    name: str = Field(max_length=255)
    description: str | None = None
    status: LifecycleStatus = LifecycleStatus.ACTIVE
    duration_days: int | None = None
    billing_period: BillingPeriod = BillingPeriod.MONTHLY
    pricing_model_id: UUID | None = None
    package_id: UUID | None = None
    age_group_id: UUID | None = None
    sport_category_id: UUID | None = None
    sport_ids: list | None = None
    features: dict | None = None
    is_default: bool = False


class MembershipPlanUpdate(BaseModel):
    name: str | None = Field(default=None, max_length=255)
    description: str | None = None
    status: LifecycleStatus | None = None
    duration_days: int | None = None
    billing_period: BillingPeriod | None = None
    pricing_model_id: UUID | None = None
    package_id: UUID | None = None
    age_group_id: UUID | None = None
    sport_category_id: UUID | None = None
    sport_ids: list | None = None
    features: dict | None = None
    is_default: bool | None = None


class MembershipPlanRead(ORMBase):
    id: UUID
    tenant_id: UUID
    sports_center_id: UUID
    code: str
    name: str
    description: str | None
    status: LifecycleStatus
    duration_days: int | None
    billing_period: BillingPeriod
    pricing_model_id: UUID | None
    package_id: UUID | None
    age_group_id: UUID | None
    sport_category_id: UUID | None
    sport_ids: list | None
    features: dict | None
    is_default: bool
    is_deleted: bool
    created_at: datetime
    updated_at: datetime


class MembershipRuleCreate(BaseModel):
    sports_center_id: UUID
    code: str = Field(max_length=50)
    name: str = Field(max_length=255)
    description: str | None = None
    status: LifecycleStatus = LifecycleStatus.ACTIVE
    kind: RuleKind = RuleKind.ELIGIBILITY
    membership_type_id: UUID | None = None
    plan_id: UUID | None = None
    package_id: UUID | None = None
    priority: int = 100
    expression: dict | None = None
    is_blocking: bool = True


class MembershipRuleUpdate(BaseModel):
    name: str | None = Field(default=None, max_length=255)
    description: str | None = None
    status: LifecycleStatus | None = None
    kind: RuleKind | None = None
    membership_type_id: UUID | None = None
    plan_id: UUID | None = None
    package_id: UUID | None = None
    priority: int | None = None
    expression: dict | None = None
    is_blocking: bool | None = None


class MembershipRuleRead(ORMBase):
    id: UUID
    tenant_id: UUID
    sports_center_id: UUID
    code: str
    name: str
    description: str | None
    status: LifecycleStatus
    kind: RuleKind
    membership_type_id: UUID | None
    plan_id: UUID | None
    package_id: UUID | None
    priority: int
    expression: dict | None
    is_blocking: bool
    is_deleted: bool
    created_at: datetime
    updated_at: datetime


class RenewalPolicyCreate(BaseModel):
    sports_center_id: UUID
    code: str = Field(max_length=50)
    name: str = Field(max_length=255)
    description: str | None = None
    status: LifecycleStatus = LifecycleStatus.ACTIVE
    auto_renew: bool = False
    renew_window_days: int | None = None
    grace_period_days: int = 0
    max_renewals: int | None = None
    pricing_model_id: UUID | None = None
    rules: dict | None = None


class RenewalPolicyUpdate(BaseModel):
    name: str | None = Field(default=None, max_length=255)
    description: str | None = None
    status: LifecycleStatus | None = None
    auto_renew: bool | None = None
    renew_window_days: int | None = None
    grace_period_days: int | None = None
    max_renewals: int | None = None
    pricing_model_id: UUID | None = None
    rules: dict | None = None


class RenewalPolicyRead(ORMBase):
    id: UUID
    tenant_id: UUID
    sports_center_id: UUID
    code: str
    name: str
    description: str | None
    status: LifecycleStatus
    auto_renew: bool
    renew_window_days: int | None
    grace_period_days: int
    max_renewals: int | None
    pricing_model_id: UUID | None
    rules: dict | None
    is_deleted: bool
    created_at: datetime
    updated_at: datetime


class FreezingRuleCreate(BaseModel):
    sports_center_id: UUID
    code: str = Field(max_length=50)
    name: str = Field(max_length=255)
    description: str | None = None
    status: LifecycleStatus = LifecycleStatus.ACTIVE
    max_freeze_days: int | None = None
    max_freeze_count: int | None = None
    min_active_days_before_freeze: int | None = None
    extend_end_date: bool = True
    requires_approval: bool = False
    rules: dict | None = None


class FreezingRuleUpdate(BaseModel):
    name: str | None = Field(default=None, max_length=255)
    description: str | None = None
    status: LifecycleStatus | None = None
    max_freeze_days: int | None = None
    max_freeze_count: int | None = None
    min_active_days_before_freeze: int | None = None
    extend_end_date: bool | None = None
    requires_approval: bool | None = None
    rules: dict | None = None


class FreezingRuleRead(ORMBase):
    id: UUID
    tenant_id: UUID
    sports_center_id: UUID
    code: str
    name: str
    description: str | None
    status: LifecycleStatus
    max_freeze_days: int | None
    max_freeze_count: int | None
    min_active_days_before_freeze: int | None
    extend_end_date: bool
    requires_approval: bool
    rules: dict | None
    is_deleted: bool
    created_at: datetime
    updated_at: datetime


class ExpirationPolicyCreate(BaseModel):
    sports_center_id: UUID
    code: str = Field(max_length=50)
    name: str = Field(max_length=255)
    description: str | None = None
    status: LifecycleStatus = LifecycleStatus.ACTIVE
    expire_after_days: int | None = None
    warn_before_days: int | None = None
    grace_period_days: int = 0
    auto_expire: bool = True
    post_expire_status: str = Field(default="expired", max_length=32)
    rules: dict | None = None


class ExpirationPolicyUpdate(BaseModel):
    name: str | None = Field(default=None, max_length=255)
    description: str | None = None
    status: LifecycleStatus | None = None
    expire_after_days: int | None = None
    warn_before_days: int | None = None
    grace_period_days: int | None = None
    auto_expire: bool | None = None
    post_expire_status: str | None = Field(default=None, max_length=32)
    rules: dict | None = None


class ExpirationPolicyRead(ORMBase):
    id: UUID
    tenant_id: UUID
    sports_center_id: UUID
    code: str
    name: str
    description: str | None
    status: LifecycleStatus
    expire_after_days: int | None
    warn_before_days: int | None
    grace_period_days: int
    auto_expire: bool
    post_expire_status: str
    rules: dict | None
    is_deleted: bool
    created_at: datetime
    updated_at: datetime
