"""
Schemas for Referral Partners and Commission Ledger.
"""

from datetime import datetime
from decimal import Decimal
from uuid import UUID

from pydantic import BaseModel, ConfigDict, Field, model_validator

from app.models.referral import ReferralType

# ── Referral Partner Schemas ───────────────────────────────────────────────────


class ReferralBase(BaseModel):
    """Base fields for referral partners (doctors, clinics, agents)."""

    name: str = Field(..., min_length=1, max_length=200, description="Partner or doctor full name")
    referral_type: ReferralType = Field(
        default=ReferralType.DOCTOR,
        description="Type: doctor, hospital, clinic, agent, or other",
    )
    code: str | None = Field(None, max_length=30, description="Unique partner code (e.g. DOC-001)")
    phone: str | None = Field(None, max_length=20, description="Contact phone")
    email: str | None = Field(None, max_length=255, description="Contact email")
    address: str | None = Field(None, description="Clinic or office address")
    commission_rate: Decimal = Field(
        default=Decimal("0.00"),
        ge=Decimal("0.00"),
        le=Decimal("100.00"),
        description="Default commission percentage (0.00 to 100.00)",
    )
    is_active: bool = Field(default=True, description="Active status")
    notes: str | None = Field(None, description="Partnership terms or notes")


class ReferralCreate(ReferralBase):
    """Payload to create a new referral partner."""

    pass


class ReferralUpdate(BaseModel):
    """Payload to update an existing referral partner."""

    name: str | None = Field(None, min_length=1, max_length=200)
    referral_type: ReferralType | None = None
    code: str | None = Field(None, max_length=30)
    phone: str | None = Field(None, max_length=20)
    email: str | None = Field(None, max_length=255)
    address: str | None = None
    commission_rate: Decimal | None = None
    is_active: bool | None = None
    notes: str | None = None

    @model_validator(mode="after")
    def validate_commission_rate(self) -> "ReferralUpdate":
        if self.commission_rate is not None:
            if self.commission_rate < Decimal("0.00") or self.commission_rate > Decimal("100.00"):
                raise ValueError("Commission rate must be between 0.00 and 100.00 percent")
        return self


class ReferralResponse(BaseModel):
    """Response representation of a referral partner."""

    id: UUID
    lab_id: UUID
    name: str
    referral_type: ReferralType
    code: str | None
    phone: str | None
    email: str | None
    address: str | None
    commission_rate: Decimal
    is_active: bool
    notes: str | None
    created_at: datetime
    updated_at: datetime

    model_config = ConfigDict(from_attributes=True)


# ── Commission Ledger Schemas ──────────────────────────────────────────────────


class CommissionEntryResponse(BaseModel):
    """Response representation of an immutable commission ledger entry."""

    id: UUID
    lab_id: UUID
    referral_id: UUID
    order_id: UUID
    created_by: UUID | None
    order_amount: Decimal
    commission_rate: Decimal
    commission_amount: Decimal
    is_settled: bool
    settled_at: datetime | None
    notes: str | None
    created_at: datetime
    updated_at: datetime
    referral_name: str | None = None
    order_number: str | None = None
    patient_name: str | None = None
    patient_code: str | None = None
    created_by_name: str | None = None

    model_config = ConfigDict(from_attributes=True)


class CommissionSettleRequest(BaseModel):
    """Payload to mark commission entry(ies) as disbursed/settled."""

    notes: str | None = Field(None, max_length=500, description="Settlement payout remarks or reference")


class RadiologistCommissionResponse(BaseModel):
    """Response representation of a radiologist commission ledger entry."""

    id: UUID
    lab_id: UUID
    radiologist_id: UUID
    order_id: UUID
    report_id: UUID
    order_amount: Decimal
    commission_rate: Decimal
    commission_amount: Decimal
    is_settled: bool
    settled_at: datetime | None
    notes: str | None
    created_at: datetime
    updated_at: datetime
    radiologist_name: str | None = None
    order_number: str | None = None

    model_config = ConfigDict(from_attributes=True)
