"""
Normalizes product data coming from different stores into ACA's canonical format.

Each store can define a `response_mapping` dict on its StoreRegistry record
that maps the store's field names to ACA field names.  For example:

    {"img": "image_url", "title": "name", "cost": "price"}

Fields not in the mapping are tried as-is against the canonical list.
"""

from typing import Dict, Optional

CANONICAL_FIELDS = {
    "id",
    "name",
    "price",
    "currency",
    "image_url",
    "description",
    "brand",
    "category",
    "product_url",
    "in_stock",
}


def normalize_product(raw: dict, store, mapping: Optional[Dict] = None) -> dict:
    """
    Convert a single raw product dict from a store response into ACA's
    normalized format.

    Parameters
    ----------
    raw : dict
        The product dict as returned by the store API.
    store : StoreRegistry
        The store record (used to tag the product).
    mapping : dict or None
        Field name mapping (store_field -> canonical_field).
    """
    mapping = mapping or {}
    reverse_map = {v: k for k, v in mapping.items()}

    def _get(canonical_name: str, default=None):
        store_field = reverse_map.get(canonical_name, canonical_name)
        return raw.get(store_field, raw.get(canonical_name, default))

    product_url = _get("product_url", "")
    if product_url and not product_url.startswith("http"):
        product_url = store.base_api_url.rstrip("/").rsplit("/api", 1)[0] + product_url

    return {
        "store_id": store.id,
        "store_name": store.name,
        "store_slug": store.slug,
        "store_logo": store.logo,
        "external_id": _get("id"),
        "name": _get("name", "Unnamed Product"),
        "price": _get("price"),
        "currency": _get("currency", "USD"),
        "image_url": _get("image_url", ""),
        "description": _get("description", ""),
        "brand": _get("brand", ""),
        "category": _get("category", ""),
        "product_url": product_url,
        "in_stock": _get("in_stock", True),
    }
