"""Smart-collection membership previews for taxonomy dashboards and push diagnostics."""

from __future__ import annotations

from typing import Any, Dict, List, Optional

from sqlalchemy import select
from sqlalchemy.orm import Session

from db.models import MasterProduct, ShopifyCollectionRegistry
from db.product_channel_taxonomy import resolve_shopify_collection_ids
from shopify.smart_collection import (
    build_smart_collection_product_context,
    evaluate_smart_collection_rules,
    smart_collection_guidance,
)


def evaluate_shopify_collection_assignments_for_sku(
    session: Session,
    *,
    master_sku: str,
    connection_id: Optional[int] = None,
    fields: Optional[Dict[str, Any]] = None,
    product_input: Optional[Dict[str, Any]] = None,
    taxonomy_category_id: Optional[str] = None,
) -> Dict[str, Any]:
    """Preview how assigned Shopify collections (manual vs smart) apply to one SKU."""
    master_sku = str(master_sku or "").strip()
    if not master_sku:
        raise ValueError("master_sku is required")

    product = session.scalar(select(MasterProduct).where(MasterProduct.sku == master_sku).limit(1))
    canonical_fields = dict(fields or _master_fields(product))
    context = build_smart_collection_product_context(
        canonical_fields,
        product_input=product_input,
        taxonomy_category_id=taxonomy_category_id,
        channel_sku=master_sku,
        price=_price_from_fields(canonical_fields),
    )

    collection_ids = resolve_shopify_collection_ids(
        session,
        master_sku=master_sku,
        connection_id=connection_id,
    )
    registry = _registry_by_collection_id(session, collection_ids, connection_id=connection_id)

    items: List[Dict[str, Any]] = []
    for collection_id in collection_ids:
        row = registry.get(collection_id)
        if row is None:
            items.append(
                {
                    "collection_id": collection_id,
                    "collection_type": "unknown",
                    "status": "missing_registry",
                    "message": "Collection is assigned in taxonomy but not found in shopify_collection_registry.",
                    "recommended_actions": ["Run Shopify pull / attribute sync to refresh collection registry."],
                }
            )
            continue

        if row.collection_type == "smart":
            evaluation = evaluate_smart_collection_rules(row.rules_json, context)
            guidance = smart_collection_guidance(
                collection_title=row.title or row.handle or collection_id,
                collection_handle=row.handle,
                evaluation=evaluation,
            )
            items.append(
                {
                    "collection_id": collection_id,
                    "collection_handle": row.handle,
                    "collection_title": row.title,
                    **guidance,
                }
            )
            continue

        items.append(
            {
                "collection_id": collection_id,
                "collection_handle": row.handle,
                "collection_title": row.title,
                "collection_type": "manual",
                "status": "manual_assignment",
                "message": "Manual collection — product will be added directly on push.",
                "recommended_actions": [],
            }
        )

    blocking = [item for item in items if item.get("collection_type") == "smart" and item.get("status") == "rule_mismatch"]
    return {
        "master_sku": master_sku,
        "connection_id": connection_id,
        "product_context": context,
        "collections": items,
        "smart_mismatch_count": len(blocking),
        "ready_for_push": len(blocking) == 0,
    }


def _registry_by_collection_id(
    session: Session,
    collection_ids: List[str],
    *,
    connection_id: Optional[int],
) -> Dict[str, ShopifyCollectionRegistry]:
    if not collection_ids:
        return {}
    stmt = select(ShopifyCollectionRegistry).where(ShopifyCollectionRegistry.collection_id.in_(collection_ids))
    if connection_id is not None:
        stmt = stmt.where(ShopifyCollectionRegistry.connection_id == connection_id)
    return {row.collection_id: row for row in session.scalars(stmt).all()}


def _master_fields(product: Optional[MasterProduct]) -> Dict[str, Any]:
    if product is None:
        return {}
    return {
        "sku": product.sku,
        "title": product.name,
        "name": product.name,
        "category_l1": product.category_l1,
        "category_l2": product.category_l2,
        "category_l3": product.category_l3,
        "collection": product.collection,
        "product_family": product.product_family,
        "vendor": product.product_family,
    }


def _price_from_fields(fields: Dict[str, Any]) -> Optional[float]:
    raw = fields.get("price")
    if raw is None or raw == "":
        return None
    try:
        return float(str(raw).replace(",", "").strip())
    except (TypeError, ValueError):
        return None
