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

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

from pydantic import BaseModel, Field


class PointsEarnRequest(BaseModel):
    """Schema for earning points from a purchase."""

    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)",
    )

    # Purchase info
    purchase_amount_cents: int = Field(
        ...,
        gt=0,
        description="Purchase amount in cents",
    )
    order_reference: str | None = Field(
        None,
        max_length=100,
        description="Order reference for tracking",
    )

    # 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",
    )


class PointsEarnResponse(BaseModel):
    """Schema for points earning response."""

    success: bool = True
    message: str = "Points earned successfully"

    # Points info
    points_earned: int
    points_per_euro: int
    purchase_amount_cents: int

    # Card state after earning
    card_id: int
    card_number: str
    points_balance: int
    total_points_earned: int

    # Location
    store_id: int | None = None


class PointsRedeemRequest(BaseModel):
    """Schema for redeeming points 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)",
    )

    # Reward selection
    reward_id: str = Field(
        ...,
        description="ID of the reward to redeem",
    )

    # 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",
    )


class PointsRedeemResponse(BaseModel):
    """Schema for points redemption response."""

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

    # Reward info
    reward_id: str
    reward_name: str
    points_spent: int

    # Card state after redemption
    card_id: int
    card_number: str
    points_balance: int
    total_points_redeemed: int

    # Location
    store_id: int | None = None


class PointsVoidRequest(BaseModel):
    """Schema for voiding points (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)",
    )

    # Points to void (use one method)
    points_to_void: int | None = Field(
        None,
        gt=0,
        description="Number of points to void",
    )
    original_transaction_id: int | None = Field(
        None,
        description="ID of original transaction to void",
    )
    order_reference: str | None = Field(
        None,
        max_length=100,
        description="Order reference to find and 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 PointsVoidResponse(BaseModel):
    """Schema for points void response."""

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

    # Void info
    points_voided: int

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

    # Location
    store_id: int | None = None


class PointsAdjustRequest(BaseModel):
    """Schema for manual points adjustment (admin)."""

    points_delta: int = Field(
        ...,
        ge=-100000,
        le=100000,
        description="Points to add (positive) or remove (negative)",
    )
    reason: str = Field(
        ...,
        min_length=5,
        max_length=500,
        description="Reason for adjustment (required)",
    )
    staff_pin: str | None = Field(
        None,
        min_length=4,
        max_length=6,
        description="Staff PIN for verification",
    )


class PointsAdjustResponse(BaseModel):
    """Schema for points adjustment response."""

    success: bool = True
    message: str = "Points adjusted successfully"

    # Adjustment info
    points_delta: int

    # Card state after adjustment
    card_id: int
    card_number: str
    points_balance: int
