"""
Pydantic schemas for User entities and password changes.
"""

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

from pydantic import BaseModel, ConfigDict, Field


class UserBase(BaseModel):
    """Common fields for a staff user."""

    name: str = Field(..., min_length=2, max_length=200, description="Staff full name")
    phone: str = Field(..., min_length=7, max_length=20, description="Phone number")
    email: str | None = Field(default=None, max_length=255, description="Optional email")
    # Plain string (not the UserRole enum) so superadmin-created custom roles
    # are assignable without a code change. Must match a row in `role` or a
    # built-in UserRole value; services validate existence.
    role: str = Field(..., min_length=2, max_length=50, description="Staff role code")
    license_no: str | None = Field(
        default=None, max_length=50, description="Council registration number (e.g. NMC No.)"
    )


class UserCreate(UserBase):
    """Payload to register a new user."""

    lab_id: UUID | None = Field(default=None, description="Branch lab ID (defaults to primary if omitted)")
    password: str = Field(..., min_length=6, description="Initial account password")
    commission_rate: Decimal | None = Field(
        default=None,
        ge=Decimal("0"),
        le=Decimal("100"),
        description="Per-report commission % (e.g. radiologist cut)",
    )


class UserUpdate(BaseModel):
    """Payload to update an existing user."""

    name: str | None = Field(default=None, min_length=2, max_length=200)
    phone: str | None = Field(default=None, min_length=7, max_length=20)
    email: str | None = Field(default=None, max_length=255)
    role: str | None = Field(default=None, min_length=2, max_length=50)
    license_no: str | None = Field(default=None, max_length=50)
    commission_rate: Decimal | None = Field(default=None, ge=Decimal("0"), le=Decimal("100"))
    is_active: bool | None = Field(default=None)


class ChangePasswordRequest(BaseModel):
    """Payload for staff member to change their own password."""

    old_password: str = Field(..., min_length=6, description="Current password")
    new_password: str = Field(..., min_length=6, description="New password")


class AdminPasswordResetRequest(BaseModel):
    """Payload for a superadmin to set any staff member's password."""

    password: str = Field(..., min_length=6, max_length=128, description="New temporary password")


class UserResponse(UserBase):
    """Representation of a user profile."""

    model_config = ConfigDict(from_attributes=True)

    id: UUID
    lab_id: UUID
    is_active: bool
    signature_image_path: str | None = None
    commission_rate: Decimal | None = None
    created_at: datetime
    updated_at: datetime
