"""Standard commerce schema — Pydantic models for common business entities.

These are the canonical representations that all providers map into.
Descriptions act as prompts — they explain what business questions
each entity can answer, enabling LLM agents to discover and use them.

Vendor-specific data (Shopify, Stripe, etc.) is transformed into these
models during the pipeline's transform step. The models are then serialized
and stored in Postgres for querying by agents and analytics engines.
"""

from datetime import datetime
from decimal import Decimal
from typing import Dict, List, Optional
from uuid import UUID, uuid4

from pydantic import BaseModel, Field


# ---------------------------------------------------------------------------
# Products
# ---------------------------------------------------------------------------


class Variant(BaseModel):
    """A specific purchasable version of a product (size, color, etc.).

    Use for: inventory tracking, pricing analysis, SKU-level demand forecasting.
    """

    id: UUID = Field(default_factory=uuid4)
    product_id: Optional[UUID] = None
    sku: Optional[str] = None
    title: str = ""
    price: Decimal = Decimal("0")
    compare_at_price: Optional[Decimal] = None
    inventory_quantity: int = 0
    weight: Optional[float] = None
    barcode: Optional[str] = None
    source_id: Optional[str] = None  # vendor-specific ID (e.g. Shopify gid)


class Product(BaseModel):
    """A product in the catalog.

    Use for: catalog analysis, product performance, category trends,
    pricing optimization, content quality assessment.
    """

    id: UUID = Field(default_factory=uuid4)
    title: str
    description: Optional[str] = None
    vendor: Optional[str] = None
    product_type: Optional[str] = None
    tags: List[str] = Field(default_factory=list)
    status: str = "active"  # active | draft | archived
    variants: List[Variant] = Field(default_factory=list)
    created_at: Optional[datetime] = None
    updated_at: Optional[datetime] = None
    source_id: Optional[str] = None


class Collection(BaseModel):
    """A grouping of products (manual or automated).

    Use for: category performance analysis, merchandising effectiveness.
    """

    id: UUID = Field(default_factory=uuid4)
    title: str
    description: Optional[str] = None
    collection_type: str = "manual"  # manual | smart
    product_ids: List[UUID] = Field(default_factory=list)
    source_id: Optional[str] = None


# ---------------------------------------------------------------------------
# Orders
# ---------------------------------------------------------------------------


class LineItem(BaseModel):
    """A single item within an order.

    Use for: product-level sales analysis, average order composition,
    discount effectiveness, variant demand signals.
    """

    id: UUID = Field(default_factory=uuid4)
    product_id: Optional[UUID] = None
    variant_id: Optional[UUID] = None
    title: str = ""
    sku: Optional[str] = None
    quantity: int = 1
    price: Decimal = Decimal("0")
    total_discount: Decimal = Decimal("0")
    source_id: Optional[str] = None


class Order(BaseModel):
    """A completed or pending customer order.

    Use for: revenue analysis, cohort analysis, customer LTV,
    demand forecasting, fulfillment tracking, promotion lift detection.
    """

    id: UUID = Field(default_factory=uuid4)
    order_number: Optional[str] = None
    customer_id: Optional[UUID] = None
    email: Optional[str] = None
    financial_status: str = "pending"  # pending | paid | refunded | partially_refunded
    fulfillment_status: Optional[str] = None  # fulfilled | partial | null
    total_price: Decimal = Decimal("0")
    subtotal_price: Decimal = Decimal("0")
    total_tax: Decimal = Decimal("0")
    total_discounts: Decimal = Decimal("0")
    currency: str = "USD"
    line_items: List[LineItem] = Field(default_factory=list)
    created_at: Optional[datetime] = None
    updated_at: Optional[datetime] = None
    source_id: Optional[str] = None


# ---------------------------------------------------------------------------
# Customers
# ---------------------------------------------------------------------------


class Customer(BaseModel):
    """A customer record.

    Use for: segmentation (RFM), LTV estimation, retention analysis,
    cohort tracking, personalized recommendations.
    """

    id: UUID = Field(default_factory=uuid4)
    email: Optional[str] = None
    first_name: Optional[str] = None
    last_name: Optional[str] = None
    orders_count: int = 0
    total_spent: Decimal = Decimal("0")
    tags: List[str] = Field(default_factory=list)
    created_at: Optional[datetime] = None
    updated_at: Optional[datetime] = None
    source_id: Optional[str] = None


# ---------------------------------------------------------------------------
# Inventory
# ---------------------------------------------------------------------------


class InventoryLevel(BaseModel):
    """Inventory quantity at a specific location.

    Use for: stock monitoring, reorder point calculations, ABC classification,
    stockout risk scoring, safety stock analysis, multi-location optimization.
    """

    id: UUID = Field(default_factory=uuid4)
    inventory_item_id: Optional[UUID] = None
    location_id: Optional[str] = None
    location_name: Optional[str] = None
    available: int = 0
    on_hand: int = 0
    incoming: int = 0
    committed: int = 0
    reserved: int = 0
    updated_at: Optional[datetime] = None
    source_id: Optional[str] = None


class InventoryItem(BaseModel):
    """An inventory item linked to a product variant.

    Use for: cost analysis, inventory valuation, SKU-level tracking,
    demand forecasting inputs.
    """

    id: UUID = Field(default_factory=uuid4)
    variant_id: Optional[UUID] = None
    sku: Optional[str] = None
    cost: Optional[Decimal] = None
    tracked: bool = True
    levels: List[InventoryLevel] = Field(default_factory=list)
    created_at: Optional[datetime] = None
    updated_at: Optional[datetime] = None
    source_id: Optional[str] = None
