"""Referral Engine DTOs — Phase 7.5."""
from __future__ import annotations

from datetime import datetime
from uuid import UUID

from pydantic import BaseModel, ConfigDict, Field

from app.models.types import (
    ReferralAttributionStatus,
    ReferralCodeStatus,
    ReferralProgramStatus,
)
from app.schemas.common import ORMBase

_FORBID = ConfigDict(extra="forbid")


class ReferralProgramCreate(BaseModel):
    model_config = _FORBID

    program_id: UUID
    code: str = Field(max_length=50)
    name: str = Field(max_length=255)
    status: ReferralProgramStatus = ReferralProgramStatus.DRAFT
    referrer_bonus_points: int = Field(default=0, ge=0)
    referee_bonus_points: int = Field(default=0, ge=0)
    max_referrals_per_member: int | None = Field(default=None, ge=1)


class ReferralProgramUpdate(BaseModel):
    model_config = _FORBID

    name: str | None = Field(default=None, max_length=255)
    status: ReferralProgramStatus | None = None
    referrer_bonus_points: int | None = Field(default=None, ge=0)
    referee_bonus_points: int | None = Field(default=None, ge=0)
    max_referrals_per_member: int | None = Field(default=None, ge=1)


class ReferralProgramRead(ORMBase):
    id: UUID
    tenant_id: UUID
    program_id: UUID
    code: str
    name: str
    status: ReferralProgramStatus
    referrer_bonus_points: int
    referee_bonus_points: int
    max_referrals_per_member: int | None
    is_deleted: bool
    created_by: str | None
    updated_by: str | None
    created_at: datetime
    updated_at: datetime


class ReferralProgramPage(BaseModel):
    items: list[ReferralProgramRead]
    total: int
    offset: int
    limit: int


class ReferralCodeIssueRequest(BaseModel):
    model_config = _FORBID

    referral_program_id: UUID
    member_id: UUID
    code: str | None = Field(default=None, max_length=50)


class ReferralCodeRead(ORMBase):
    id: UUID
    tenant_id: UUID
    referral_program_id: UUID
    program_id: UUID
    member_id: UUID
    code: str
    status: ReferralCodeStatus
    uses_count: int
    created_by: str | None
    created_at: datetime
    updated_at: datetime


class ReferralCodePage(BaseModel):
    items: list[ReferralCodeRead]
    total: int
    offset: int
    limit: int


class ReferralAttributeRequest(BaseModel):
    model_config = _FORBID

    code: str = Field(max_length=50)
    referee_member_id: UUID
    idempotency_key: str | None = Field(default=None, max_length=100)


class ReferralCancelRequest(BaseModel):
    model_config = _FORBID

    reason: str | None = Field(default=None, max_length=500)


class ReferralAttributionRead(ORMBase):
    id: UUID
    tenant_id: UUID
    referral_program_id: UUID
    referral_code_id: UUID
    program_id: UUID
    referrer_member_id: UUID
    referee_member_id: UUID
    status: ReferralAttributionStatus
    referrer_ledger_entry_id: UUID | None
    referee_ledger_entry_id: UUID | None
    idempotency_key: str | None
    converted_at: datetime | None
    rewarded_at: datetime | None
    cancelled_at: datetime | None
    cancel_reason: str | None
    actor_user_id: str | None
    created_at: datetime
    updated_at: datetime


class ReferralAttributionPage(BaseModel):
    items: list[ReferralAttributionRead]
    total: int
    offset: int
    limit: int
