"""
Patient schemas for Munal LMS.
"""

from __future__ import annotations

from datetime import date, datetime
from decimal import Decimal
from uuid import UUID

from pydantic import BaseModel, ConfigDict, EmailStr, Field

from app.models.patient import Gender


class PatientBase(BaseModel):
    """Base fields for patient representation."""

    name: str = Field(..., min_length=1, max_length=200, description="Full name of the patient")
    gender: Gender = Field(..., description="Biological sex")
    phone: str = Field(..., min_length=7, max_length=20, description="Primary contact phone number")
    date_of_birth: date | None = Field(None, description="Date of birth")
    age: int | None = Field(None, ge=0, le=150, description="Age in years if DOB unknown")
    email: EmailStr | None = Field(None, description="Optional email for report delivery")
    address: str | None = Field(None, description="Residential address")
    country: str | None = Field("Nepal", max_length=100, description="Country")
    height_cm: Decimal | None = Field(None, ge=10, le=300, description="Height in centimetres")
    weight_kg: Decimal | None = Field(None, ge=1, le=500, description="Weight in kilograms")


class PatientCreate(PatientBase):
    """Payload to register a new patient."""

    lab_id: UUID | None = Field(default=None, description="Branch lab ID (defaults to primary if omitted)")


class PortalCredentialsUpdate(BaseModel):
    """Desk reset of portal login: new username (phone) and/or fresh PIN."""

    phone: str | None = Field(None, min_length=7, max_length=20, description="New login phone number")
    rotate_pin: bool = Field(False, description="Issue a fresh bill PIN (returned once)")


class PatientUpdate(BaseModel):
    """Payload to update an existing patient."""

    name: str | None = Field(None, min_length=1, max_length=200)
    gender: Gender | None = None
    phone: str | None = Field(None, min_length=7, max_length=20)
    date_of_birth: date | None = None
    age: int | None = Field(None, ge=0, le=150)
    email: EmailStr | None = None
    address: str | None = None
    country: str | None = Field(None, max_length=100)
    height_cm: Decimal | None = Field(None, ge=10, le=300)
    weight_kg: Decimal | None = Field(None, ge=1, le=500)


class PatientResponse(BaseModel):
    """Schema returned for a patient."""

    id: UUID
    lab_id: UUID
    patient_code: str
    name: str
    gender: Gender
    phone: str
    date_of_birth: date | None = None
    age: int | None = None
    email: str | None = None
    address: str | None = None
    country: str | None = None
    height_cm: Decimal | None = None
    weight_kg: Decimal | None = None
    created_at: datetime
    updated_at: datetime

    model_config = ConfigDict(from_attributes=True)


class PortalCredentialsResponse(BaseModel):
    """Updated patient plus the fresh PIN when rotated (shown once)."""

    patient: PatientResponse
    portal_pin: str | None = Field(None, description="Fresh PIN — display once, never stored")
