# generated by datamodel-codegen:
#   filename:  openapi.yaml
#   timestamp: 2026-06-25T09:55:15+00:00

from __future__ import annotations

from enum import Enum
from typing import Annotated
from uuid import UUID

from pydantic import AnyUrl, AwareDatetime, BaseModel, EmailStr, Field


class Money(BaseModel):
    amount: int
    """
    Amount in smallest currency unit (e.g. cents)
    """
    currency: Annotated[str, Field(examples=['USD'], pattern='^[A-Z]{3}$')]


class Address(BaseModel):
    line1: str
    line2: str | None = None
    city: str
    state: str | None = None
    postal_code: str | None = None
    country: Annotated[str, Field(examples=['US'], pattern='^[A-Z]{2}$')]


class ProductStatus(Enum):
    active = 'active'
    inactive = 'inactive'
    archived = 'archived'


class Product(BaseModel):
    id: UUID
    name: Annotated[str, Field(max_length=255)]
    description: str | None = None
    price: Money
    images: list[AnyUrl] | None = []
    category_id: UUID | None = None
    status: ProductStatus
    inventory_count: Annotated[int | None, Field(ge=0)] = None
    created_at: AwareDatetime
    updated_at: AwareDatetime | None = None


class ProductCategory(BaseModel):
    id: UUID
    name: str
    parent_id: UUID | None = None


class OrderStatus(Enum):
    pending = 'pending'
    confirmed = 'confirmed'
    processing = 'processing'
    shipped = 'shipped'
    delivered = 'delivered'
    cancelled = 'cancelled'
    refunded = 'refunded'


class ProductSnapshot(BaseModel):
    name: str | None = None


class OrderItem(BaseModel):
    product_id: UUID
    quantity: Annotated[int, Field(ge=1)]
    unit_price: Money
    product_snapshot: ProductSnapshot | None = None
    """
    Denormalized product name at time of order
    """


class Order(BaseModel):
    id: UUID
    user_id: UUID
    items: Annotated[list[OrderItem], Field(min_length=1)]
    status: OrderStatus
    subtotal: Money
    tax: Money | None = None
    shipping_cost: Money | None = None
    total: Money
    shipping_address: Address | None = None
    notes: str | None = None
    created_at: AwareDatetime
    updated_at: AwareDatetime | None = None


class PaymentMethodType(Enum):
    card = 'card'
    apple_pay = 'apple_pay'
    google_pay = 'google_pay'
    bank_transfer = 'bank_transfer'


class CheckoutStatus(Enum):
    open = 'open'
    processing = 'processing'
    completed = 'completed'
    expired = 'expired'
    failed = 'failed'


class CheckoutLineItem(BaseModel):
    product_id: UUID
    quantity: Annotated[int, Field(ge=1)]


class Checkout(BaseModel):
    id: UUID
    user_id: UUID
    line_items: Annotated[list[CheckoutLineItem], Field(min_length=1)]
    shipping_address: Address | None = None
    payment_method_type: PaymentMethodType | None = None
    promo_code: str | None = None
    status: CheckoutStatus
    order_id: UUID | None = None
    """
    Set when checkout completes and order is created
    """
    expires_at: AwareDatetime | None = None
    created_at: AwareDatetime
    updated_at: AwareDatetime | None = None


class UserRole(Enum):
    customer = 'customer'
    admin = 'admin'
    vendor = 'vendor'


class User(BaseModel):
    id: UUID
    email: EmailStr
    name: str | None = None
    role: UserRole
    created_at: AwareDatetime


class ErrorCode(Enum):
    validation_error = 'validation_error'
    not_found = 'not_found'
    unauthorized = 'unauthorized'
    forbidden = 'forbidden'
    conflict = 'conflict'
    payment_failed = 'payment_failed'
    out_of_stock = 'out_of_stock'
    internal_error = 'internal_error'


class ErrorDetail(BaseModel):
    code: ErrorCode
    message: str
    field: str | None = None
    """
    Field path for validation errors
    """


class ApiError(BaseModel):
    error: ErrorDetail
