/**
 * AddToCartButton – primitive that fires V4 `Product Added` on click.
 *
 * The cart-side action is the consumer's responsibility (they pass
 * `onAddToCart`); this primitive owns the V4 emission so every
 * consumer storefront — cartello, demo-stores, future templates —
 * inherits Product Added tracking for free.
 *
 * Algolia hybrid pattern (spec Section 6G — "Cart and conversion event
 * ownership"): cart APIs live in the consumer storefront, but the
 * tracking shim sits in ui-sdk so the Seekora SDK is the canonical
 * emission seam for the entire 17-event V4 taxonomy.
 *
 * Behaviour on click:
 *   1. Fire `Product Added` (event 7) with the product fields the
 *      Segment Spec requires (object_id, product_id, price, quantity,
 *      currency, search_id?, surface).
 *   2. Invoke the consumer's `onAddToCart` callback (the cart-side
 *      action). Fired AFTER analytics so navigation/side-effects in
 *      the callback don't race the emission.
 *
 * search_id resolution: pass NOTHING for `search_id` to let the SDK's
 * 3-layer fallback (in-memory → sessionStorage → URL) attribute the
 * event. Passing `search_id: undefined` explicitly would defeat the
 * resolver — the SDK's track() wrapper now treats `undefined` as
 * unsupplied and runs the resolver, but it's still cleaner to omit
 * the key entirely.
 *
 * SCRUM-259 Phase 4c — task #74.
 */
import React, { useCallback } from "react";
import { clsx } from "clsx";
import { trackProductAdded, emitFilterConvertedForActiveFilters, } from "@seekora-ai/search-sdk";
import { useTrackContext } from "../SearchProvider";
/**
 * Coerce price (number | string | undefined) into a clean number for
 * the V4 wire shape. Strips currency symbols, commas, and whitespace
 * from strings. Returns `undefined` when no usable value — Product
 * Added accepts a missing price (the Spec marks it optional for ad-hoc
 * surfaces).
 */
function coercePrice(price) {
    if (price == null)
        return undefined;
    if (typeof price === "number")
        return Number.isFinite(price) ? price : undefined;
    // Strip everything that isn't a digit, decimal point, or minus sign.
    const cleaned = price.replace(/[^0-9.\-]/g, "");
    if (!cleaned)
        return undefined;
    const n = Number.parseFloat(cleaned);
    return Number.isFinite(n) ? n : undefined;
}
function resolveObjectId(p) {
    if (p.id != null)
        return String(p.id);
    if (p.product_id != null)
        return String(p.product_id);
    return "";
}
function resolveProductName(p) {
    return p.title ?? p.name ?? p.primaryText;
}
export function AddToCartButton({ product, quantity = 1, onAddToCart, surface = "results_page", searchId, trackingEnabled = true, children = "Add to Cart", className, style, disabled, ...buttonRest }) {
    const ctx = useTrackContext();
    const handleClick = useCallback(async (e) => {
        e.stopPropagation();
        e.preventDefault();
        if (disabled)
            return;
        // 1. Emit V4 Product Added first. Wrap in try/catch so a
        // throwing tracker never blocks the cart-side action.
        if (trackingEnabled && ctx) {
            try {
                const objectId = resolveObjectId(product);
                const price = coercePrice(product.price);
                // Build the Algolia-derived array wire shape mandated by the
                // V4 ProductAddedProperties schema: `object_ids[]` +
                // `object_data[]` are required, even for a single-line add.
                // OMIT search_id when the caller didn't pass one — the SDK's
                // track() wrapper runs resolveSearchId() for unsupplied keys.
                const dataItem = {
                    object_type: "product",
                    quantity,
                    currency: product.currency ?? "USD",
                };
                if (price !== undefined)
                    dataItem.price = price;
                const name = resolveProductName(product);
                if (name)
                    dataItem.name = name;
                if (product.variant_id != null) {
                    dataItem.variant_id = String(product.variant_id);
                }
                if (product.sku)
                    dataItem.sku = product.sku;
                if (product.category)
                    dataItem.category = product.category;
                const payload = {
                    object_ids: [objectId],
                    object_data: [dataItem],
                    surface,
                };
                if (searchId)
                    payload.search_id = searchId;
                trackProductAdded(ctx, payload);
                // Algolia hybrid pattern: fan out one Filter Converted per
                // active filter. Reads the active-filter session-state
                // (populated by SearchStateManager.emitFacetApplied) and
                // emits as many Filter Converted events as filters were
                // active in the 30-min attribution window. No-op when
                // nothing is active.
                emitFilterConvertedForActiveFilters(ctx, {
                    conversion_type: "addToCart",
                    ...(price !== undefined ? { value: price } : {}),
                    currency: product.currency ?? "USD",
                    ...(searchId ? { search_id: searchId } : {}),
                });
            }
            catch {
                // Never let analytics break the cart flow.
            }
        }
        // 2. Fire the consumer's cart-side action. Await it so any
        // navigation it triggers happens after analytics, but don't let
        // a thrown error swallow the click — re-throw so the consumer's
        // own error boundary can catch.
        if (onAddToCart) {
            await onAddToCart(product, quantity);
        }
    }, [
        ctx,
        disabled,
        onAddToCart,
        product,
        quantity,
        searchId,
        surface,
        trackingEnabled,
    ]);
    return (React.createElement("button", { type: "button", onClick: handleClick, disabled: disabled, className: clsx("seekora-add-to-cart-button", className), style: style, ...buttonRest }, children));
}
