from __future__ import annotations

from typing import Any, Dict, List, Optional

from db.source_imports import normalize_column_key


# Plytix v1 product-attribute search (not top-level attributes/search).
ATTRIBUTE_SEARCH_PATH = "attributes/product/search"


def fetch_plytix_attribute_definitions(
    client: Any,
    *,
    page_size: int = 100,
    max_pages: int = 50,
    search_path: str = ATTRIBUTE_SEARCH_PATH,
) -> List[Dict[str, Any]]:
    """Best-effort API fetch: search IDs then GET each attribute for full metadata."""
    from app.jobs.plytix_pull import _fetch_product_pages, _normalize_search_path

    path = _normalize_search_path(search_path)
    if path == "attributes/search":
        path = ATTRIBUTE_SEARCH_PATH

    stubs = _fetch_product_pages(client, path, page_size=page_size, max_pages=max_pages)
    if not stubs:
        return []

    rows: List[Dict[str, Any]] = []
    seen: set[str] = set()
    for stub in stubs:
        if not isinstance(stub, dict):
            continue
        attr_id = str(stub.get("id") or "").strip()
        if attr_id and attr_id not in seen:
            seen.add(attr_id)
            detail = _fetch_attribute_detail(client, attr_id)
            if detail:
                rows.append(detail)
                continue
        if _looks_like_full_attribute(stub):
            rows.append(stub)
    return rows


def _fetch_attribute_detail(client: Any, attr_id: str) -> Optional[Dict[str, Any]]:
    try:
        payload = client.get(f"attributes/product/{attr_id}")
    except Exception:
        return None
    data = payload.get("data")
    if isinstance(data, list) and data:
        item = data[0]
        return item if isinstance(item, dict) else None
    if isinstance(data, dict):
        return data
    return None


def _looks_like_full_attribute(item: Dict[str, Any]) -> bool:
    return bool(
        item.get("label")
        or item.get("name")
        or item.get("attribute_code")
        or item.get("code")
    )


def attribute_row_from_api(item: Dict[str, Any]) -> Optional[Dict[str, Any]]:
    if not isinstance(item, dict):
        return None
    code = normalize_column_key(
        item.get("label")
        or item.get("name")
        or item.get("attribute_code")
        or item.get("code")
        or item.get("key")
        or ""
    )
    if not code:
        return None
    label = str(item.get("name") or item.get("label") or code).strip()
    data_type = str(
        item.get("type_class")
        or item.get("filter_type")
        or item.get("type")
        or item.get("data_type")
        or item.get("attribute_type")
        or "text"
    ).strip()
    groups = item.get("groups") or item.get("group") or item.get("group_name")
    group = ""
    if isinstance(groups, list):
        group = ", ".join(str(g) for g in groups if g)
    elif groups:
        group = str(groups)
    return {
        "attribute_code": code,
        "label": label,
        "data_type": data_type,
        "group_name": group,
        "required": item.get("required") or item.get("is_required"),
        "active": item.get("active", True),
        "notes": "plytix_api_pull",
    }
