# app/modules/loyalty/schemas/stamp.py
"""
Pydantic schemas for stamp operations.

Merchant-based stamps:
- Stamps earned at any store count toward merchant total
- Stamps can be redeemed at any store within the merchant
- Supports voiding stamps for returns
"""

from datetime import datetime

from pydantic import BaseModel, Field


class StampRequest(BaseModel):
    """Schema for adding a stamp to a card."""

    card_id: int | None = Field(
        None,
        description="Card ID (use this or qr_code)",
    )
    qr_code: str | None = Field(
        None,
        description="QR code data from card scan",
    )
    card_number: str | None = Field(
        None,
        description="Card number (manual entry)",
    )

    # Authentication
    staff_pin: str | None = Field(
        None,
        min_length=4,
        max_length=6,
        description="Staff PIN for verification",
    )

    # Categories (what was sold — multi-select)
    category_ids: list[int] | None = Field(
        None,
        description="Transaction category IDs",
    )

    # Optional metadata
    notes: str | None = Field(
        None,
        max_length=500,
        description="Optional note about this stamp",
    )


class StampResponse(BaseModel):
    """Schema for stamp operation response."""

    success: bool = True
    message: str = "Stamp added successfully"

    # Card state after stamp
    card_id: int
    card_number: str
    stamp_count: int
    stamps_target: int
    stamps_until_reward: int

    # Did this trigger a reward?
    reward_earned: bool = False
    reward_description: str | None = None

    # Cooldown info
    next_stamp_available_at: datetime | None = None

    # Today's activity
    stamps_today: int
    stamps_remaining_today: int

    # Location
    store_id: int | None = None


class StampRedeemRequest(BaseModel):
    """Schema for redeeming stamps for a reward."""

    card_id: int | None = Field(
        None,
        description="Card ID (use this or qr_code)",
    )
    qr_code: str | None = Field(
        None,
        description="QR code data from card scan",
    )
    card_number: str | None = Field(
        None,
        description="Card number (manual entry)",
    )

    # Authentication
    staff_pin: str | None = Field(
        None,
        min_length=4,
        max_length=6,
        description="Staff PIN for verification",
    )

    # Optional metadata
    notes: str | None = Field(
        None,
        max_length=500,
        description="Optional note about this redemption",
    )


class StampRedeemResponse(BaseModel):
    """Schema for stamp redemption response."""

    success: bool = True
    message: str = "Reward redeemed successfully"

    # Card state after redemption
    card_id: int
    card_number: str
    stamp_count: int  # Should be 0 after redemption
    stamps_target: int

    # Reward info
    reward_description: str
    total_redemptions: int  # Lifetime redemptions for this card

    # Location
    store_id: int | None = None


class StampVoidRequest(BaseModel):
    """Schema for voiding stamps (for returns)."""

    card_id: int | None = Field(
        None,
        description="Card ID (use this or qr_code)",
    )
    qr_code: str | None = Field(
        None,
        description="QR code data from card scan",
    )
    card_number: str | None = Field(
        None,
        description="Card number (manual entry)",
    )

    # Stamps to void (use one method)
    stamps_to_void: int | None = Field(
        None,
        gt=0,
        description="Number of stamps to void",
    )
    original_transaction_id: int | None = Field(
        None,
        description="ID of original transaction to void",
    )

    # Authentication
    staff_pin: str | None = Field(
        None,
        min_length=4,
        max_length=6,
        description="Staff PIN for verification",
    )

    # Required metadata
    notes: str | None = Field(
        None,
        max_length=500,
        description="Reason for voiding",
    )


class StampVoidResponse(BaseModel):
    """Schema for stamp void response."""

    success: bool = True
    message: str = "Stamps voided successfully"

    # Void info
    stamps_voided: int

    # Card state after void
    card_id: int
    card_number: str
    stamp_count: int

    # Location
    store_id: int | None = None
