"""Point ledger DTOs — Phase 7.2."""
from __future__ import annotations

from datetime import datetime
from uuid import UUID

from pydantic import BaseModel, ConfigDict, Field

from app.models.types import LedgerEntryType, PointAccountStatus
from app.schemas.common import ORMBase

_FORBID = ConfigDict(extra="forbid")


class PointEarnRequest(BaseModel):
    model_config = _FORBID

    amount: int = Field(gt=0)
    reason: str | None = Field(default=None, max_length=500)
    idempotency_key: str | None = Field(default=None, max_length=100)
    reference_type: str | None = Field(default=None, max_length=50)
    reference_id: str | None = Field(default=None, max_length=100)
    expires_at: datetime | None = None
    metadata_json: dict | None = None


class PointRedeemRequest(BaseModel):
    model_config = _FORBID

    amount: int = Field(gt=0)
    reason: str | None = Field(default=None, max_length=500)
    idempotency_key: str | None = Field(default=None, max_length=100)
    reference_type: str | None = Field(default=None, max_length=50)
    reference_id: str | None = Field(default=None, max_length=100)
    metadata_json: dict | None = None


class PointAdjustRequest(BaseModel):
    model_config = _FORBID

    amount: int  # signed
    reason: str = Field(max_length=500)
    idempotency_key: str | None = Field(default=None, max_length=100)
    reference_type: str | None = Field(default=None, max_length=50)
    reference_id: str | None = Field(default=None, max_length=100)
    metadata_json: dict | None = None


class PointExpireRequest(BaseModel):
    model_config = _FORBID

    amount: int = Field(gt=0)
    reason: str | None = Field(default=None, max_length=500)
    idempotency_key: str | None = Field(default=None, max_length=100)
    reference_type: str | None = Field(default=None, max_length=50)
    reference_id: str | None = Field(default=None, max_length=100)
    metadata_json: dict | None = None


class PointLedgerEntryRead(ORMBase):
    id: UUID
    tenant_id: UUID
    point_account_id: UUID
    program_id: UUID
    member_id: UUID
    entry_type: LedgerEntryType
    amount: int
    balance_after: int
    idempotency_key: str | None
    reference_type: str | None
    reference_id: str | None
    reason: str | None
    metadata_json: dict | None
    expires_at: datetime | None
    actor_user_id: str | None
    created_at: datetime


class PointBalanceRead(BaseModel):
    point_account_id: UUID
    member_id: UUID
    program_id: UUID
    status: PointAccountStatus
    balance: int
    currency_name: str


class PointLedgerPage(BaseModel):
    items: list[PointLedgerEntryRead]
    total: int
    offset: int
    limit: int
