"""Data models used by the SDK."""

from __future__ import annotations

from dataclasses import dataclass, field
from typing import Any, Dict, List, Optional


@dataclass
class BasketItem:
    """A single item in the basket."""

    id: str
    name: str
    price: float
    quantity: int = 1
    is_eco: bool = False
    on_sale: bool = False
    index: int = 0

    def __post_init__(self) -> None:
        if not self.id:
            raise ValueError("BasketItem id must be non-empty")
        if self.price < 0:
            raise ValueError("BasketItem price must be non-negative")
        if self.quantity < 1:
            raise ValueError("BasketItem quantity must be at least 1")


# ---------------------------------------------------------------------------
# v2 structured response models
# ---------------------------------------------------------------------------


@dataclass
class Product:
    """A product from structured search results."""

    product_number: str
    name: str
    price: Optional[float] = None
    list_price: Optional[float] = None
    unit_price: Optional[float] = None
    unit_price_label: Optional[str] = None
    description: Optional[str] = None
    is_eco: bool = False
    available: bool = True
    low_stock: bool = False
    relevance_rank: Optional[int] = None


@dataclass
class SearchResults:
    """Structured search response."""

    products: List[Product]
    total: Optional[int] = None
    query: str = ""

    @classmethod
    def from_dict(cls, data: Dict[str, Any]) -> "SearchResults":
        products = [
            Product(**{k: v for k, v in p.items() if k in Product.__dataclass_fields__})
            for p in data.get("products", [])
        ]
        return cls(
            products=products,
            total=data.get("total"),
            query=data.get("query", ""),
        )


@dataclass
class BasketItemV2:
    """A structured basket item from v2 endpoints."""

    product_number: str
    name: str
    price: float = 0.0
    quantity: int = 1
    line_total: float = 0.0
    is_eco: bool = False
    on_sale: bool = False
    campaign_label: Optional[str] = None
    explanation: Optional[str] = None


@dataclass
class BasketItems:
    """Structured basket contents."""

    items: List[BasketItemV2]
    total_price: float = 0.0
    item_count: int = 0

    @classmethod
    def from_dict(cls, data: Dict[str, Any]) -> "BasketItems":
        items = [
            BasketItemV2(**{k: v for k, v in it.items() if k in BasketItemV2.__dataclass_fields__})
            for it in data.get("items", [])
        ]
        return cls(
            items=items,
            total_price=data.get("total_price", 0.0),
            item_count=data.get("item_count", 0),
        )


@dataclass
class BatchAddResult:
    """Result of a batch add operation."""

    added: List[Dict[str, Any]] = field(default_factory=list)
    failed: List[Dict[str, Any]] = field(default_factory=list)
    duplicates: List[Dict[str, Any]] = field(default_factory=list)
    total_price: float = 0.0
    item_count: int = 0

    @classmethod
    def from_dict(cls, data: Dict[str, Any]) -> "BatchAddResult":
        return cls(
            added=data.get("added", []),
            failed=data.get("failed", []),
            duplicates=data.get("duplicates", []),
            total_price=data.get("total_price", 0.0),
            item_count=data.get("item_count", 0),
        )
