"""
Helpers to normalize remote MCP payloads into local DB models.
"""

from __future__ import annotations

import json
import zlib
from typing import Any, Dict, List, Optional

from db.models import ProductCatalog, UserDemographics


def _stable_numeric_id(record: Dict[str, Any]) -> int:
    raw = json.dumps(record, sort_keys=True)
    return zlib.crc32(raw.encode("utf-8")) & 0xFFFFFFFF


def _first_non_empty(*candidates: Any, default: Optional[str] = None) -> Optional[str]:
    for candidate in candidates:
        if isinstance(candidate, str):
            candidate = candidate.strip()
        if candidate:
            return str(candidate)
    return default


def _coerce_price(value: Any) -> Optional[float]:
    if value is None:
        return None
    if isinstance(value, (int, float)):
        return float(value)
    if isinstance(value, str):
        cleaned = "".join(ch for ch in value if ch.isdigit() or ch in ".-")
        if cleaned:
            try:
                return float(cleaned)
            except ValueError:
                return None
    return None


def _resolve_price(record: Dict[str, Any]) -> float:
    candidates = [
        record.get("price"),
        record.get("price_usd"),
        record.get("priceUSD"),
        record.get("priceMin"),
        record.get("minPrice"),
    ]
    for candidate in candidates:
        price = _coerce_price(candidate)
        if price is not None:
            return price

    price_range = record.get("priceRange") or record.get("price_range")
    if isinstance(price_range, dict):
        nested_keys = [
            ("minVariantPrice", "amount"),
            ("maxVariantPrice", "amount"),
            ("min", "value"),
            ("max", "value"),
        ]
        for outer, inner in nested_keys:
            node = price_range.get(outer)
            if isinstance(node, dict):
                price = _coerce_price(node.get(inner) or node.get("amount"))
                if price is not None:
                    return price
        price = _coerce_price(price_range.get("amount") or price_range.get("value"))
        if price is not None:
            return price

    variants = record.get("variants")
    if isinstance(variants, list):
        for variant in variants:
            if isinstance(variant, dict):
                price = _coerce_price(variant.get("price"))
                if price is not None:
                    return price

    return 0.0


def _resolve_image(record: Dict[str, Any]) -> Optional[str]:
    image = (
        record.get("image_url")
        or record.get("imageUrl")
        or record.get("image")
        or record.get("featuredImage")
    )
    if isinstance(image, str):
        return image
    if isinstance(image, dict):
        for key in ("url", "src", "originalSrc"):
            if image.get(key):
                return image[key]
    if isinstance(image, list):
        for item in image:
            if isinstance(item, str) and item.strip():
                return item.strip()
            if isinstance(item, dict):
                url = item.get("url") or item.get("src")
                if url:
                    return url
    return None


def normalize_product(record: Dict[str, Any]) -> Optional[ProductCatalog]:
    product_id = record.get("product_id") or record.get("productId") or record.get("id")
    try:
        if product_id is not None:
            product_id = int(str(product_id).strip())
    except ValueError:
        product_id = None
    if product_id is None:
        product_id = _stable_numeric_id(record)

    product_name = _first_non_empty(
        record.get("product_name"),
        record.get("title"),
        record.get("name"),
        record.get("handle"),
        default=f"Product-{product_id}",
    )
    if not product_name:
        return None

    brand_name = _first_non_empty(
        record.get("brand"),
        record.get("brand_name"),
        record.get("brandName"),
        record.get("vendor"),
        default="Unknown Brand",
    ) or "Unknown Brand"

    description = record.get("description") or record.get("body_html") or record.get("bodyHtml")
    if isinstance(description, list):
        description = " ".join(str(item).strip() for item in description if item)

    category = _first_non_empty(
        record.get("category"),
        record.get("product_type"),
        record.get("productType"),
        record.get("primaryCategory"),
        default="general",
    ) or "general"

    return ProductCatalog(
        product_id=int(product_id),
        product_name=product_name,
        brand_name=brand_name,
        category=category,
        price=_resolve_price(record),
        description=description,
        image_url=_resolve_image(record),
    )


def normalize_customer(record: Dict[str, Any]) -> UserDemographics:
    first = (record.get("firstName") or "").strip()
    last = (record.get("lastName") or "").strip()
    email = (record.get("email") or "").strip()
    if first or last:
        base_name = " ".join(part for part in [first, last] if part)
    elif email:
        base_name = email
    else:
        base_name = record.get("id") or "Customer"
    if email and email.lower() not in base_name.lower():
        name = f"{base_name} ({email})"
    else:
        name = base_name

    return UserDemographics(
        user_id=None,  # type: ignore[arg-type]
        name=name,
        gender=None,
        age=None,
        user_cluster_id=0,
    )

