"""Sports Center foundation DTOs — Phase 9.0."""
from __future__ import annotations

from datetime import date, datetime
from uuid import UUID

from pydantic import BaseModel, Field

from app.models.types import (
    ConnectorCapability,
    DeviceStatus,
    FacilityKind,
    LifecycleStatus,
    LockerStatus,
    MembershipStatus,
    StaffKind,
)
from app.schemas.common import ORMBase


class SportsCenterCreate(BaseModel):
    code: str = Field(max_length=50)
    name: str = Field(max_length=255)
    description: str | None = None
    status: LifecycleStatus = LifecycleStatus.DRAFT
    legal_name: str | None = Field(default=None, max_length=255)
    timezone: str = Field(default="Asia/Tehran", max_length=64)
    language: str = Field(default="fa", max_length=16)
    currency_code: str = Field(default="IRR", max_length=3)
    settings: dict | None = None


class SportsCenterUpdate(BaseModel):
    name: str | None = Field(default=None, max_length=255)
    description: str | None = None
    status: LifecycleStatus | None = None
    legal_name: str | None = Field(default=None, max_length=255)
    timezone: str | None = Field(default=None, max_length=64)
    language: str | None = Field(default=None, max_length=16)
    currency_code: str | None = Field(default=None, max_length=3)
    settings: dict | None = None
    version: int | None = None


class SportsCenterRead(ORMBase):
    id: UUID
    tenant_id: UUID
    code: str
    name: str
    description: str | None
    status: LifecycleStatus
    legal_name: str | None
    timezone: str
    language: str
    currency_code: str
    settings: dict | None
    version: int
    is_deleted: bool
    created_by: str | None
    updated_by: str | None
    created_at: datetime
    updated_at: datetime


class BranchCreate(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
    address: dict | None = None
    timezone: str | None = Field(default=None, max_length=64)
    working_hours: dict | None = None
    metadata_json: dict | None = None


class BranchUpdate(BaseModel):
    name: str | None = Field(default=None, max_length=255)
    description: str | None = None
    status: LifecycleStatus | None = None
    address: dict | None = None
    timezone: str | None = Field(default=None, max_length=64)
    working_hours: dict | None = None
    metadata_json: dict | None = None


class BranchRead(ORMBase):
    id: UUID
    tenant_id: UUID
    sports_center_id: UUID
    code: str
    name: str
    description: str | None
    status: LifecycleStatus
    address: dict | None
    timezone: str | None
    working_hours: dict | None
    metadata_json: dict | None
    is_deleted: bool
    created_by: str | None
    updated_by: str | None
    created_at: datetime
    updated_at: datetime


class SportCreate(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
    category: str | None = Field(default=None, max_length=100)
    attributes: dict | None = None


class SportUpdate(BaseModel):
    name: str | None = Field(default=None, max_length=255)
    description: str | None = None
    status: LifecycleStatus | None = None
    category: str | None = Field(default=None, max_length=100)
    attributes: dict | None = None


class SportRead(ORMBase):
    id: UUID
    tenant_id: UUID
    sports_center_id: UUID
    code: str
    name: str
    description: str | None
    status: LifecycleStatus
    category: str | None
    attributes: dict | None
    is_deleted: bool
    created_by: str | None
    updated_by: str | None
    created_at: datetime
    updated_at: datetime


class MembershipTypeCreate(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
    policies: dict | None = None
    sport_ids: list | None = None
    package_id: UUID | None = None
    plan_id: UUID | None = None
    pricing_model_id: UUID | None = None
    age_group_id: UUID | None = None
    sport_category_id: UUID | None = None
    renewal_policy_id: UUID | None = None
    freezing_rule_id: UUID | None = None
    expiration_policy_id: UUID | None = None
    is_transferable: bool = False
    sort_order: int = 0


class MembershipTypeUpdate(BaseModel):
    name: str | None = Field(default=None, max_length=255)
    description: str | None = None
    status: LifecycleStatus | None = None
    duration_days: int | None = None
    policies: dict | None = None
    sport_ids: list | None = None
    package_id: UUID | None = None
    plan_id: UUID | None = None
    pricing_model_id: UUID | None = None
    age_group_id: UUID | None = None
    sport_category_id: UUID | None = None
    renewal_policy_id: UUID | None = None
    freezing_rule_id: UUID | None = None
    expiration_policy_id: UUID | None = None
    is_transferable: bool | None = None
    sort_order: int | None = None


class MembershipTypeRead(ORMBase):
    id: UUID
    tenant_id: UUID
    sports_center_id: UUID
    code: str
    name: str
    description: str | None
    status: LifecycleStatus
    duration_days: int | None
    policies: dict | None
    sport_ids: list | None
    package_id: UUID | None
    plan_id: UUID | None
    pricing_model_id: UUID | None
    age_group_id: UUID | None
    sport_category_id: UUID | None
    renewal_policy_id: UUID | None
    freezing_rule_id: UUID | None
    expiration_policy_id: UUID | None
    is_transferable: bool
    sort_order: int
    is_deleted: bool
    created_by: str | None
    updated_by: str | None
    created_at: datetime
    updated_at: datetime


class MembershipCreate(BaseModel):
    sports_center_id: UUID
    membership_type_id: UUID
    display_name: str = Field(max_length=255)
    membership_number: str | None = Field(default=None, max_length=50)
    member_id: UUID | None = None
    branch_id: UUID | None = None
    email: str | None = Field(default=None, max_length=255)
    mobile: str | None = Field(default=None, max_length=50)
    external_customer_ref: str | None = Field(default=None, max_length=100)
    external_crm_contact_ref: str | None = Field(default=None, max_length=100)
    status: MembershipStatus = MembershipStatus.PENDING
    starts_on: date | None = None
    ends_on: date | None = None
    profile: dict | None = None
    custom_fields: dict | None = None


class MembershipUpdate(BaseModel):
    display_name: str | None = Field(default=None, max_length=255)
    member_id: UUID | None = None
    branch_id: UUID | None = None
    email: str | None = Field(default=None, max_length=255)
    mobile: str | None = Field(default=None, max_length=50)
    external_customer_ref: str | None = Field(default=None, max_length=100)
    external_crm_contact_ref: str | None = Field(default=None, max_length=100)
    status: MembershipStatus | None = None
    starts_on: date | None = None
    ends_on: date | None = None
    freeze_starts_on: date | None = None
    freeze_ends_on: date | None = None
    profile: dict | None = None
    custom_fields: dict | None = None
    version: int | None = None


class MembershipRead(ORMBase):
    id: UUID
    tenant_id: UUID
    sports_center_id: UUID
    branch_id: UUID | None
    membership_type_id: UUID
    member_id: UUID | None
    membership_number: str
    display_name: str
    email: str | None
    mobile: str | None
    external_customer_ref: str | None
    external_crm_contact_ref: str | None
    status: MembershipStatus
    starts_on: date | None
    ends_on: date | None
    freeze_starts_on: date | None
    freeze_ends_on: date | None
    profile: dict | None
    custom_fields: dict | None
    version: int
    is_deleted: bool
    created_by: str | None
    updated_by: str | None
    created_at: datetime
    updated_at: datetime


class CoachCreate(BaseModel):
    sports_center_id: UUID
    code: str = Field(max_length=50)
    display_name: str = Field(max_length=255)
    branch_id: UUID | None = None
    email: str | None = Field(default=None, max_length=255)
    mobile: str | None = Field(default=None, max_length=50)
    status: LifecycleStatus = LifecycleStatus.ACTIVE
    sport_ids: list | None = None
    qualifications: dict | None = None
    external_user_ref: str | None = Field(default=None, max_length=100)
    staff_kind: StaffKind = StaffKind.COACH
    bio: str | None = None
    hire_date: date | None = None
    payroll_external_ref: str | None = Field(default=None, max_length=100)
    sports_role_id: UUID | None = None


class CoachUpdate(BaseModel):
    display_name: str | None = Field(default=None, max_length=255)
    branch_id: UUID | None = None
    email: str | None = Field(default=None, max_length=255)
    mobile: str | None = Field(default=None, max_length=50)
    status: LifecycleStatus | None = None
    sport_ids: list | None = None
    qualifications: dict | None = None
    external_user_ref: str | None = Field(default=None, max_length=100)
    staff_kind: StaffKind | None = None
    bio: str | None = None
    hire_date: date | None = None
    payroll_external_ref: str | None = Field(default=None, max_length=100)
    sports_role_id: UUID | None = None


class CoachRead(ORMBase):
    id: UUID
    tenant_id: UUID
    sports_center_id: UUID
    branch_id: UUID | None
    code: str
    display_name: str
    email: str | None
    mobile: str | None
    status: LifecycleStatus
    sport_ids: list | None
    qualifications: dict | None
    external_user_ref: str | None
    staff_kind: StaffKind
    bio: str | None
    hire_date: date | None
    payroll_external_ref: str | None
    sports_role_id: UUID | None
    is_deleted: bool
    created_by: str | None
    updated_by: str | None
    created_at: datetime
    updated_at: datetime


class SportsRoleCreate(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
    permission_codes: list | None = None


class SportsRoleUpdate(BaseModel):
    name: str | None = Field(default=None, max_length=255)
    description: str | None = None
    status: LifecycleStatus | None = None
    permission_codes: list | None = None


class SportsRoleRead(ORMBase):
    id: UUID
    tenant_id: UUID
    sports_center_id: UUID
    code: str
    name: str
    description: str | None
    status: LifecycleStatus
    permission_codes: list | None
    is_deleted: bool
    created_by: str | None
    updated_by: str | None
    created_at: datetime
    updated_at: datetime


class SportsPermissionCreate(BaseModel):
    code: str = Field(max_length=100)
    name: str = Field(max_length=255)
    description: str | None = None
    sports_center_id: UUID | None = None
    status: LifecycleStatus = LifecycleStatus.ACTIVE


class SportsPermissionUpdate(BaseModel):
    name: str | None = Field(default=None, max_length=255)
    description: str | None = None
    status: LifecycleStatus | None = None


class SportsPermissionRead(ORMBase):
    id: UUID
    tenant_id: UUID
    sports_center_id: UUID | None
    code: str
    name: str
    description: str | None
    status: LifecycleStatus
    is_deleted: bool
    created_by: str | None
    updated_by: str | None
    created_at: datetime
    updated_at: datetime


class FacilityCreate(BaseModel):
    sports_center_id: UUID
    code: str = Field(max_length=50)
    name: str = Field(max_length=255)
    description: str | None = None
    branch_id: UUID | None = None
    kind: FacilityKind = FacilityKind.GENERAL
    status: LifecycleStatus = LifecycleStatus.ACTIVE
    capacity: int | None = None
    attributes: dict | None = None


class FacilityUpdate(BaseModel):
    name: str | None = Field(default=None, max_length=255)
    description: str | None = None
    branch_id: UUID | None = None
    kind: FacilityKind | None = None
    status: LifecycleStatus | None = None
    capacity: int | None = None
    attributes: dict | None = None


class FacilityRead(ORMBase):
    id: UUID
    tenant_id: UUID
    sports_center_id: UUID
    branch_id: UUID | None
    code: str
    name: str
    description: str | None
    kind: FacilityKind
    status: LifecycleStatus
    capacity: int | None
    attributes: dict | None
    is_deleted: bool
    created_by: str | None
    updated_by: str | None
    created_at: datetime
    updated_at: datetime


class CourtCreate(BaseModel):
    sports_center_id: UUID
    code: str = Field(max_length=50)
    name: str = Field(max_length=255)
    branch_id: UUID | None = None
    facility_id: UUID | None = None
    status: LifecycleStatus = LifecycleStatus.ACTIVE
    surface: str | None = Field(default=None, max_length=100)
    attributes: dict | None = None


class CourtUpdate(BaseModel):
    name: str | None = Field(default=None, max_length=255)
    branch_id: UUID | None = None
    facility_id: UUID | None = None
    status: LifecycleStatus | None = None
    surface: str | None = Field(default=None, max_length=100)
    attributes: dict | None = None


class CourtRead(ORMBase):
    id: UUID
    tenant_id: UUID
    sports_center_id: UUID
    branch_id: UUID | None
    facility_id: UUID | None
    code: str
    name: str
    status: LifecycleStatus
    surface: str | None
    attributes: dict | None
    is_deleted: bool
    created_by: str | None
    updated_by: str | None
    created_at: datetime
    updated_at: datetime


class RoomCreate(BaseModel):
    sports_center_id: UUID
    code: str = Field(max_length=50)
    name: str = Field(max_length=255)
    branch_id: UUID | None = None
    facility_id: UUID | None = None
    status: LifecycleStatus = LifecycleStatus.ACTIVE
    capacity: int | None = None
    attributes: dict | None = None


class RoomUpdate(BaseModel):
    name: str | None = Field(default=None, max_length=255)
    branch_id: UUID | None = None
    facility_id: UUID | None = None
    status: LifecycleStatus | None = None
    capacity: int | None = None
    attributes: dict | None = None


class RoomRead(ORMBase):
    id: UUID
    tenant_id: UUID
    sports_center_id: UUID
    branch_id: UUID | None
    facility_id: UUID | None
    code: str
    name: str
    status: LifecycleStatus
    capacity: int | None
    attributes: dict | None
    is_deleted: bool
    created_by: str | None
    updated_by: str | None
    created_at: datetime
    updated_at: datetime


class LockerRoomCreate(BaseModel):
    sports_center_id: UUID
    code: str = Field(max_length=50)
    name: str = Field(max_length=255)
    branch_id: UUID | None = None
    status: LifecycleStatus = LifecycleStatus.ACTIVE
    attributes: dict | None = None


class LockerRoomUpdate(BaseModel):
    name: str | None = Field(default=None, max_length=255)
    branch_id: UUID | None = None
    status: LifecycleStatus | None = None
    attributes: dict | None = None


class LockerRoomRead(ORMBase):
    id: UUID
    tenant_id: UUID
    sports_center_id: UUID
    branch_id: UUID | None
    code: str
    name: str
    status: LifecycleStatus
    attributes: dict | None
    is_deleted: bool
    created_by: str | None
    updated_by: str | None
    created_at: datetime
    updated_at: datetime


class LockerCreate(BaseModel):
    sports_center_id: UUID
    locker_room_id: UUID
    code: str = Field(max_length=50)
    label: str | None = Field(default=None, max_length=100)
    status: LockerStatus = LockerStatus.AVAILABLE
    attributes: dict | None = None


class LockerUpdate(BaseModel):
    label: str | None = Field(default=None, max_length=100)
    status: LockerStatus | None = None
    attributes: dict | None = None
    version: int | None = None


class LockerAssignRequest(BaseModel):
    membership_id: UUID
    version: int | None = None


class LockerRead(ORMBase):
    id: UUID
    tenant_id: UUID
    sports_center_id: UUID
    locker_room_id: UUID
    code: str
    label: str | None
    status: LockerStatus
    assigned_membership_id: UUID | None
    assigned_at: datetime | None
    attributes: dict | None
    version: int
    is_deleted: bool
    created_by: str | None
    updated_by: str | None
    created_at: datetime
    updated_at: datetime


class DeviceProviderCreate(BaseModel):
    code: str = Field(max_length=50)
    name: str = Field(max_length=255)
    capability: ConnectorCapability = ConnectorCapability.CUSTOM
    adapter_key: str = Field(max_length=100)
    status: LifecycleStatus = LifecycleStatus.ACTIVE
    config_schema: dict | None = None
    settings: dict | None = None


class DeviceProviderUpdate(BaseModel):
    name: str | None = Field(default=None, max_length=255)
    capability: ConnectorCapability | None = None
    adapter_key: str | None = Field(default=None, max_length=100)
    status: LifecycleStatus | None = None
    config_schema: dict | None = None
    settings: dict | None = None


class DeviceProviderRead(ORMBase):
    id: UUID
    tenant_id: UUID
    code: str
    name: str
    capability: ConnectorCapability
    adapter_key: str
    status: LifecycleStatus
    config_schema: dict | None
    settings: dict | None
    is_deleted: bool
    created_by: str | None
    updated_by: str | None
    created_at: datetime
    updated_at: datetime


class DeviceCreate(BaseModel):
    sports_center_id: UUID
    code: str = Field(max_length=50)
    name: str = Field(max_length=255)
    branch_id: UUID | None = None
    device_provider_id: UUID | None = None
    capability: ConnectorCapability = ConnectorCapability.CUSTOM
    status: DeviceStatus = DeviceStatus.REGISTERED
    location_ref: str | None = Field(default=None, max_length=100)
    external_device_ref: str | None = Field(default=None, max_length=100)
    settings: dict | None = None


class DeviceUpdate(BaseModel):
    name: str | None = Field(default=None, max_length=255)
    branch_id: UUID | None = None
    device_provider_id: UUID | None = None
    capability: ConnectorCapability | None = None
    status: DeviceStatus | None = None
    location_ref: str | None = Field(default=None, max_length=100)
    external_device_ref: str | None = Field(default=None, max_length=100)
    settings: dict | None = None
    version: int | None = None


class DeviceRead(ORMBase):
    id: UUID
    tenant_id: UUID
    sports_center_id: UUID
    branch_id: UUID | None
    device_provider_id: UUID | None
    code: str
    name: str
    capability: ConnectorCapability
    status: DeviceStatus
    location_ref: str | None
    external_device_ref: str | None
    settings: dict | None
    version: int
    is_deleted: bool
    created_by: str | None
    updated_by: str | None
    created_at: datetime
    updated_at: datetime


class AttendanceGatewayCreate(BaseModel):
    sports_center_id: UUID
    code: str = Field(max_length=50)
    name: str = Field(max_length=255)
    branch_id: UUID | None = None
    status: LifecycleStatus = LifecycleStatus.ACTIVE
    primary_provider_id: UUID | None = None
    fallback_provider_id: UUID | None = None
    device_ids: list | None = None
    policies: dict | None = None


class AttendanceGatewayUpdate(BaseModel):
    name: str | None = Field(default=None, max_length=255)
    branch_id: UUID | None = None
    status: LifecycleStatus | None = None
    primary_provider_id: UUID | None = None
    fallback_provider_id: UUID | None = None
    device_ids: list | None = None
    policies: dict | None = None


class AttendanceGatewayRead(ORMBase):
    id: UUID
    tenant_id: UUID
    sports_center_id: UUID
    branch_id: UUID | None
    code: str
    name: str
    status: LifecycleStatus
    primary_provider_id: UUID | None
    fallback_provider_id: UUID | None
    device_ids: list | None
    policies: dict | None
    is_deleted: bool
    created_by: str | None
    updated_by: str | None
    created_at: datetime
    updated_at: datetime


class SportsConfigurationCreate(BaseModel):
    sports_center_id: UUID
    code: str = Field(max_length=50)
    branch_id: UUID | None = None
    working_hours: dict | None = None
    membership_policies: dict | None = None
    attendance_policies: dict | None = None
    booking_policies: dict | None = None
    waiting_list: dict | None = None
    custom_fields: dict | None = None
    timezone: str = Field(default="Asia/Tehran", max_length=64)
    language: str = Field(default="fa", max_length=16)
    currency_code: str = Field(default="IRR", max_length=3)


class SportsConfigurationUpdate(BaseModel):
    working_hours: dict | None = None
    membership_policies: dict | None = None
    attendance_policies: dict | None = None
    booking_policies: dict | None = None
    waiting_list: dict | None = None
    custom_fields: dict | None = None
    timezone: str | None = Field(default=None, max_length=64)
    language: str | None = Field(default=None, max_length=16)
    currency_code: str | None = Field(default=None, max_length=3)
    version: int | None = None


class SportsConfigurationRead(ORMBase):
    id: UUID
    tenant_id: UUID
    sports_center_id: UUID
    branch_id: UUID | None
    code: str
    working_hours: dict | None
    membership_policies: dict | None
    attendance_policies: dict | None
    booking_policies: dict | None
    waiting_list: dict | None
    custom_fields: dict | None
    timezone: str
    language: str
    currency_code: str
    version: int
    is_deleted: bool
    created_by: str | None
    updated_by: str | None
    created_at: datetime
    updated_at: datetime


class SportsEventCreate(BaseModel):
    sports_center_id: UUID
    code: str = Field(max_length=50)
    title: str = Field(max_length=255)
    description: str | None = None
    branch_id: UUID | None = None
    sport_id: UUID | None = None
    facility_id: UUID | None = None
    coach_id: UUID | None = None
    status: LifecycleStatus = LifecycleStatus.DRAFT
    starts_at: datetime | None = None
    ends_at: datetime | None = None
    capacity: int | None = None
    attributes: dict | None = None


class SportsEventUpdate(BaseModel):
    title: str | None = Field(default=None, max_length=255)
    description: str | None = None
    branch_id: UUID | None = None
    sport_id: UUID | None = None
    facility_id: UUID | None = None
    coach_id: UUID | None = None
    status: LifecycleStatus | None = None
    starts_at: datetime | None = None
    ends_at: datetime | None = None
    capacity: int | None = None
    attributes: dict | None = None


class SportsEventRead(ORMBase):
    id: UUID
    tenant_id: UUID
    sports_center_id: UUID
    branch_id: UUID | None
    sport_id: UUID | None
    facility_id: UUID | None
    coach_id: UUID | None
    code: str
    title: str
    description: str | None
    status: LifecycleStatus
    starts_at: datetime | None
    ends_at: datetime | None
    capacity: int | None
    attributes: dict | None
    is_deleted: bool
    created_by: str | None
    updated_by: str | None
    created_at: datetime
    updated_at: datetime


class SportsSettingUpsert(BaseModel):
    key: str = Field(max_length=100)
    value: dict | None = None
    description: str | None = None
    sports_center_id: UUID | None = None
    branch_id: UUID | None = None


class SportsSettingRead(ORMBase):
    id: UUID
    tenant_id: UUID
    sports_center_id: UUID | None
    branch_id: UUID | None
    key: str
    value: dict | None
    description: str | None
    is_deleted: bool
    created_by: str | None
    updated_by: str | None
    created_at: datetime
    updated_at: datetime


class SportsAuditLogRead(ORMBase):
    id: UUID
    tenant_id: UUID
    entity_type: str
    entity_id: UUID
    action: str
    actor_user_id: str | None
    changes: dict | None
    message: str | None
    created_at: datetime
