# app/modules/loyalty/schemas/pin.py
"""
Pydantic schemas for staff PIN operations.
"""

from datetime import datetime

from pydantic import BaseModel, ConfigDict, Field


class PinCreate(BaseModel):
    """Schema for creating a staff PIN."""

    name: str = Field(
        ...,
        min_length=1,
        max_length=100,
        description="Staff member name",
    )
    staff_id: str | None = Field(
        None,
        max_length=50,
        description="Optional employee ID",
    )
    pin: str = Field(
        ...,
        min_length=4,
        max_length=6,
        pattern="^[0-9]+$",
        description="4-6 digit PIN",
    )


class PinCreateForMerchant(PinCreate):
    """PinCreate from the merchant portal — carries the target store_id in
    the body since the merchant has no per-store auth context (unlike the
    store-side endpoint which reads store_id from the JWT)."""

    store_id: int = Field(..., gt=0, description="Store this PIN belongs to")


class PinUpdate(BaseModel):
    """Schema for updating a staff PIN."""

    model_config = ConfigDict(from_attributes=True)

    name: str | None = Field(
        None,
        min_length=1,
        max_length=100,
    )
    staff_id: str | None = Field(
        None,
        max_length=50,
    )
    pin: str | None = Field(
        None,
        min_length=4,
        max_length=6,
        pattern="^[0-9]+$",
        description="New PIN (if changing)",
    )
    is_active: bool | None = None


class PinResponse(BaseModel):
    """Schema for staff PIN response (never includes actual PIN)."""

    model_config = ConfigDict(from_attributes=True)

    id: int
    name: str
    staff_id: str | None = None
    is_active: bool
    is_locked: bool = False
    locked_until: datetime | None = None
    last_used_at: datetime | None = None
    created_at: datetime


class PinListResponse(BaseModel):
    """Schema for listing staff PINs."""

    pins: list[PinResponse]
    total: int


class PinDetailResponse(PinResponse):
    """Extended PIN response including store context for cross-store listings."""

    store_id: int | None = None
    store_name: str | None = None


class PinDetailListResponse(BaseModel):
    """Schema for listing staff PINs with store context."""

    pins: list[PinDetailResponse]
    total: int


class PinForDeviceResponse(PinResponse):
    """Pin response for a paired terminal device.

    Includes the bcrypt ``pin_hash`` so the tablet can verify a typed
    PIN locally without a network round-trip. This shape is ONLY served
    by the device-only endpoint (``GET /pins/for-device``) — every other
    pin endpoint stays hash-less.
    """

    pin_hash: str


class PinForDeviceListResponse(BaseModel):
    pins: list[PinForDeviceResponse]
    total: int


class PinVerifyRequest(BaseModel):
    """Schema for verifying a staff PIN."""

    pin: str = Field(
        ...,
        min_length=4,
        max_length=6,
        pattern="^[0-9]+$",
        description="PIN to verify",
    )


class PinVerifyResponse(BaseModel):
    """Schema for PIN verification response."""

    valid: bool
    staff_name: str | None = None
    remaining_attempts: int | None = None
    locked_until: datetime | None = None
