/**
 * CurrentRefinements Component
 *
 * Displays currently active filters/refinements with ability to clear them.
 * Supports StateManager auto-sync, display variants, layout modes, and animations.
 */
import React, { useState, useEffect, useRef, useMemo } from "react";
import { useSearchContext } from "./SearchProvider";
import { useSearchState } from "../hooks/useSearchState";
import { clsx } from "clsx";
import { ensureSeekoraStyles } from "../styles/inject";
export const CurrentRefinements = ({ refinements: refinementsProp, onRefinementClear, onClearAll, renderRefinement, showClearAll = true, variant = "chips", layout = "horizontal", fieldColors, renderCloseIcon, className, style, theme: customTheme, excludeFields, clearAllLabel = "Clear all filters", }) => {
    useEffect(() => {
        ensureSeekoraStyles();
    }, []);
    const { theme } = useSearchContext();
    const { refinements: stateRefinements, removeRefinement, clearRefinements, } = useSearchState();
    const refinementsTheme = customTheme || {};
    // Format a numeric value for display (auto-detect price fields)
    const formatRangeValue = (field, val) => {
        const f = field.toLowerCase();
        if (f.includes("price") || f.includes("cost") || f.includes("amount")) {
            return `$${val.toLocaleString(undefined, {
                minimumFractionDigits: 2,
                maximumFractionDigits: 2,
            })}`;
        }
        return val.toLocaleString();
    };
    // Create a stable serialized key from stateRefinements to detect actual changes
    const stateRefinementsKey = stateRefinements
        .map((r) => `${r.field}:${r.value}`)
        .sort()
        .join("|");
    // Use props if provided, otherwise auto-read from StateManager
    // Combines >= / <= range refinements into single formatted pills
    const refinements = useMemo(() => {
        if (refinementsProp !== undefined) {
            return refinementsProp;
        }
        const rangeMap = new Map();
        const nonRange = [];
        stateRefinements.forEach((r) => {
            const minMatch = r.value.match(/^>=(\d+(?:\.\d+)?)$/);
            const maxMatch = r.value.match(/^<=(\d+(?:\.\d+)?)$/);
            if (minMatch || maxMatch) {
                if (!rangeMap.has(r.field))
                    rangeMap.set(r.field, {});
                const entry = rangeMap.get(r.field);
                if (minMatch)
                    entry.minVal = parseFloat(minMatch[1]);
                if (maxMatch)
                    entry.maxVal = parseFloat(maxMatch[1]);
            }
            else {
                nonRange.push({ field: r.field, value: r.value });
            }
        });
        rangeMap.forEach((range, field) => {
            let displayValue;
            if (range.minVal !== undefined && range.maxVal !== undefined) {
                displayValue = `${formatRangeValue(field, range.minVal)} – ${formatRangeValue(field, range.maxVal)}`;
            }
            else if (range.minVal !== undefined) {
                displayValue = `≥ ${formatRangeValue(field, range.minVal)}`;
            }
            else if (range.maxVal !== undefined) {
                displayValue = `≤ ${formatRangeValue(field, range.maxVal)}`;
            }
            else {
                return;
            }
            nonRange.push({ field, value: "__range__", displayValue });
        });
        const merged = nonRange;
        if (excludeFields && excludeFields.length > 0) {
            const excluded = new Set(excludeFields);
            return merged.filter((r) => !excluded.has(r.field));
        }
        return merged;
    }, [refinementsProp, stateRefinementsKey, excludeFields]);
    // Track items for entry/exit animations
    const [visibleItems, setVisibleItems] = useState(new Set());
    const [exitingItems, setExitingItems] = useState(new Set());
    const prevRefinementsRef = useRef([]);
    useEffect(() => {
        const currentKeys = new Set(refinements.map((r) => `${r.field}:${r.value}`));
        const prevKeys = new Set(prevRefinementsRef.current.map((r) => `${r.field}:${r.value}`));
        // Detect removed items for exit animation
        const removed = new Set();
        prevKeys.forEach((key) => {
            if (!currentKeys.has(key))
                removed.add(key);
        });
        let timer;
        if (removed.size > 0) {
            setExitingItems(removed);
            // Remove after animation completes
            timer = setTimeout(() => setExitingItems(new Set()), 200);
        }
        // Mark new items for entry animation
        setVisibleItems(currentKeys);
        prevRefinementsRef.current = [...refinements];
        return () => {
            if (timer !== undefined)
                clearTimeout(timer);
        };
    }, [refinements]);
    const handleClear = (field, value) => {
        if (refinementsProp === undefined) {
            if (value === "__range__") {
                // Clear all range refinements for this field
                const rangeRefs = stateRefinements.filter((r) => r.field === field && (/^>=/.test(r.value) || /^<=/.test(r.value)));
                rangeRefs.forEach((r, i) => removeRefinement(field, r.value, i === rangeRefs.length - 1));
            }
            else {
                removeRefinement(field, value);
            }
        }
        if (onRefinementClear) {
            onRefinementClear(field, value);
        }
    };
    const handleClearAll = () => {
        // If synced with StateManager, auto-clear all via StateManager
        if (refinementsProp === undefined) {
            clearRefinements();
        }
        if (onClearAll) {
            onClearAll();
        }
    };
    const defaultCloseIcon = () => (React.createElement("span", { "aria-hidden": "true", className: "seekora-current-refinements__close-icon" }, "\u00D7"));
    const defaultRenderRefinement = (refinement, index) => {
        const key = `${refinement.field}:${refinement.value}`;
        const fieldColor = fieldColors?.[refinement.field];
        const isExiting = exitingItems.has(key);
        // Per-field color escape hatch (similar to Facets swatch pattern)
        const chipStyle = {
            ...(fieldColor
                ? { "--seekora-chip-color": fieldColor }
                : {}),
            ...(isExiting
                ? {
                    opacity: 0,
                    transform: "scale(0.8)",
                    transition: "all 200ms ease-in-out",
                }
                : {}),
        };
        return (React.createElement("div", { key: `${key}-${index}`, className: clsx("seekora-current-refinements__chip", refinementsTheme.item, refinementsTheme.chip), role: "listitem", "data-field": refinement.field, "data-value": refinement.value, style: Object.keys(chipStyle).length > 0 ? chipStyle : undefined },
            variant !== "badges" && (React.createElement("span", { className: refinementsTheme.label },
                refinement.label || refinement.field,
                ":")),
            React.createElement("span", { className: refinementsTheme.value }, refinement.displayValue || refinement.value),
            React.createElement("button", { type: "button", onClick: () => handleClear(refinement.field, refinement.value), className: clsx("seekora-current-refinements__chip-remove", refinementsTheme.clearButton), "aria-label": `Clear ${refinement.label || refinement.field}: ${refinement.value}` }, renderCloseIcon ? renderCloseIcon() : defaultCloseIcon())));
    };
    // Group refinements by field for grouped layout
    const groupedRefinements = layout === "grouped"
        ? refinements.reduce((acc, r) => {
            if (!acc[r.field])
                acc[r.field] = [];
            acc[r.field].push(r);
            return acc;
        }, {})
        : null;
    // Determine data-layout: grouped layout maps to 'grouped', rest are 'horizontal'/'vertical'
    const dataLayout = layout === "vertical" ? "vertical" : "horizontal";
    // Determine data-variant: map internal variant names to BEM data-variant values
    const dataVariant = variant === "pills"
        ? "pills"
        : variant === "tags"
            ? "tags"
            : variant === "badges"
                ? "badges"
                : "chips";
    return (React.createElement("div", { className: clsx("seekora-current-refinements", refinementsTheme.container, className), "data-variant": dataVariant, "data-layout": layout === "grouped" ? "grouped" : dataLayout, style: style }, refinements.length > 0 && (React.createElement(React.Fragment, null,
        layout === "grouped" && groupedRefinements ? (Object.entries(groupedRefinements).map(([field, items]) => (React.createElement("div", { key: field, className: clsx("seekora-current-refinements__group", refinementsTheme.group) },
            React.createElement("div", { className: clsx("seekora-current-refinements__group-header", refinementsTheme.groupLabel) }, items[0]?.label || field),
            React.createElement("div", { role: "list", className: refinementsTheme.list }, items.map((refinement, index) => {
                return renderRefinement
                    ? renderRefinement(refinement, index)
                    : defaultRenderRefinement(refinement, index);
            })))))) : (React.createElement("div", { role: "list", className: refinementsTheme.list }, refinements.map((refinement, index) => {
            return renderRefinement
                ? renderRefinement(refinement, index)
                : defaultRenderRefinement(refinement, index);
        }))),
        showClearAll && refinements.length > 1 && (React.createElement("button", { type: "button", onClick: handleClearAll, className: clsx("seekora-current-refinements__clear-all", refinementsTheme.clearAllButton) }, clearAllLabel))))));
};
