/**
 * 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';
const TRANSITIONS = {
    fast: '150ms ease-in-out',
    normal: '200ms ease-in-out',
    slow: '300ms ease-in-out',
};
/** Get variant-specific styles */
const getVariantStyles = (variant, themeColors, themeSpacing, themeBorderRadius, fieldColor) => {
    const baseBg = fieldColor || `var(--seekora-refinement-bg, ${themeColors.hover})`;
    const baseColor = `var(--seekora-refinement-color, ${themeColors.text})`;
    const baseBorder = `var(--seekora-refinement-border, ${themeColors.border})`;
    switch (variant) {
        case 'tags':
            return {
                display: 'inline-flex',
                alignItems: 'center',
                padding: `2px ${themeSpacing.medium}`,
                backgroundColor: baseBg,
                border: `1px solid ${baseBorder}`,
                borderRadius: `var(--seekora-refinement-radius, 4px)`,
                fontSize: '12px',
                color: baseColor,
                fontWeight: 500,
            };
        case 'pills':
            return {
                display: 'inline-flex',
                alignItems: 'center',
                padding: `${themeSpacing.small} ${themeSpacing.medium}`,
                backgroundColor: baseBg,
                border: 'none',
                borderRadius: `var(--seekora-refinement-radius, 9999px)`,
                fontSize: '13px',
                color: baseColor,
            };
        case 'badges':
            return {
                display: 'inline-flex',
                alignItems: 'center',
                padding: `3px ${themeSpacing.small}`,
                backgroundColor: themeColors.primary,
                border: 'none',
                borderRadius: `var(--seekora-refinement-radius, 4px)`,
                fontSize: '11px',
                color: '#fff',
                fontWeight: 600,
                textTransform: 'uppercase',
                letterSpacing: '0.5px',
            };
        case 'text-list':
            return {
                display: 'flex',
                alignItems: 'center',
                padding: `${themeSpacing.small} 0`,
                backgroundColor: 'transparent',
                border: 'none',
                borderBottom: `1px solid ${baseBorder}`,
                borderRadius: '0',
                fontSize: '14px',
                color: baseColor,
            };
        case 'chips':
        default:
            return {
                display: 'inline-flex',
                alignItems: 'center',
                padding: `${themeSpacing.small} ${themeSpacing.medium}`,
                backgroundColor: baseBg,
                border: `1px solid ${baseBorder}`,
                borderRadius: `var(--seekora-refinement-radius, ${typeof themeBorderRadius === 'string' ? themeBorderRadius : themeBorderRadius.medium})`,
                fontSize: '13px',
                color: baseColor,
            };
    }
};
/** Get variant-specific class name from theme */
const getVariantClass = (variant, refinementsTheme) => {
    switch (variant) {
        case 'tags': return refinementsTheme.tag;
        case 'pills': return refinementsTheme.pill;
        case 'badges': return refinementsTheme.badge;
        case 'chips': return refinementsTheme.chip;
        default: return refinementsTheme.item;
    }
};
export const CurrentRefinements = ({ refinements: refinementsProp, onRefinementClear, onClearAll, renderRefinement, showClearAll = true, variant = 'chips', layout = 'horizontal', fieldColors, renderCloseIcon, className, style, theme: customTheme, excludeFields, }) => {
    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
    // (needed because state manager mutates the array in place)
    const stateRefinementsKey = useMemo(() => stateRefinements.map(r => `${r.field}:${r.value}`).sort().join('|'), [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);
        });
        if (removed.size > 0) {
            setExitingItems(removed);
            // Remove after animation completes
            setTimeout(() => setExitingItems(new Set()), 200);
        }
        // Mark new items for entry animation
        setVisibleItems(currentKeys);
        prevRefinementsRef.current = [...refinements];
    }, [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", style: { lineHeight: 1 } }, "\u00D7"));
    const defaultRenderRefinement = (refinement, index) => {
        const key = `${refinement.field}:${refinement.value}`;
        const fieldColor = fieldColors?.[refinement.field];
        const isEntering = visibleItems.has(key) && !prevRefinementsRef.current.some(r => `${r.field}:${r.value}` === key);
        const variantStyles = getVariantStyles(variant, theme.colors, theme.spacing, theme.borderRadius, fieldColor);
        const variantClass = getVariantClass(variant, refinementsTheme);
        return (React.createElement("div", { key: `${key}-${index}`, className: clsx(refinementsTheme.item, variantClass), role: "listitem", style: {
                ...variantStyles,
                margin: layout === 'vertical'
                    ? `0 0 ${theme.spacing.small} 0`
                    : `0 ${theme.spacing.small} ${theme.spacing.small} 0`,
                transition: `all ${TRANSITIONS.normal}`,
                opacity: exitingItems.has(key) ? 0 : 1,
                transform: exitingItems.has(key) ? 'scale(0.8)' : 'scale(1)',
                animation: isEntering ? 'seekoraChipIn 200ms ease-out' : undefined,
            } },
            variant !== 'badges' && (React.createElement("span", { className: refinementsTheme.label, style: {
                    marginRight: theme.spacing.small,
                    fontWeight: '500',
                    opacity: 0.7,
                } },
                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: refinementsTheme.clearButton, style: {
                    border: 'none',
                    backgroundColor: 'transparent',
                    color: 'inherit',
                    cursor: 'pointer',
                    fontSize: '14px',
                    padding: '0 0 0 6px',
                    display: 'flex',
                    alignItems: 'center',
                    justifyContent: 'center',
                    borderRadius: '50%',
                    transition: `opacity ${TRANSITIONS.fast}`,
                    opacity: 0.6,
                }, "aria-label": `Clear ${refinement.label || refinement.field}: ${refinement.value}`, onMouseEnter: e => (e.currentTarget.style.opacity = '1'), onMouseLeave: e => (e.currentTarget.style.opacity = '0.6') }, 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;
    const containerStyles = {
        ...style,
        // When a custom list theme is provided, make the container transparent to layout
        // so the list div becomes the direct layout child (enables overflow scroll from parent)
        ...(refinementsTheme.list && !style?.display ? { display: 'contents' } : {}),
    };
    const listStyles = {
        display: 'flex',
        flexDirection: layout === 'vertical' ? 'column' : 'row',
        alignItems: layout === 'vertical' ? 'flex-start' : 'center',
        marginBottom: showClearAll && refinements.length > 0 ? theme.spacing.medium : 0,
        // Only apply flex-wrap if no custom list theme is provided (let theme classes control wrapping)
        ...(!refinementsTheme.list ? { flexWrap: layout === 'vertical' ? 'nowrap' : 'wrap' } : {}),
    };
    return (React.createElement("div", { className: clsx(refinementsTheme.container, className), style: containerStyles },
        React.createElement("style", null, `
        @keyframes seekoraChipIn {
          from { opacity: 0; transform: scale(0.8); }
          to { opacity: 1; transform: scale(1); }
        }
      `),
        refinements.length > 0 && (React.createElement(React.Fragment, null,
            layout === 'grouped' && groupedRefinements ? (Object.entries(groupedRefinements).map(([field, items]) => (React.createElement("div", { key: field, className: refinementsTheme.group, style: { marginBottom: theme.spacing.medium } },
                React.createElement("div", { className: refinementsTheme.groupLabel, style: {
                        fontSize: theme.typography.fontSize.small,
                        fontWeight: 600,
                        color: theme.colors.text,
                        marginBottom: theme.spacing.small,
                        textTransform: 'capitalize',
                    } }, items[0]?.label || field),
                React.createElement("div", { role: "list", style: listStyles }, items.map((refinement, index) => {
                    return renderRefinement
                        ? renderRefinement(refinement, index)
                        : defaultRenderRefinement(refinement, index);
                })))))) : (React.createElement("div", { role: "list", className: refinementsTheme.list, style: listStyles }, refinements.map((refinement, index) => {
                return renderRefinement
                    ? renderRefinement(refinement, index)
                    : defaultRenderRefinement(refinement, index);
            }))),
            showClearAll && refinements.length > 1 && (React.createElement("button", { type: "button", onClick: handleClearAll, className: refinementsTheme.clearAllButton, style: {
                    padding: `${theme.spacing.small} ${theme.spacing.medium}`,
                    border: `1px solid ${theme.colors.border}`,
                    borderRadius: typeof theme.borderRadius === 'string' ? theme.borderRadius : theme.borderRadius.medium,
                    backgroundColor: theme.colors.background,
                    color: theme.colors.text,
                    cursor: 'pointer',
                    fontSize: theme.typography.fontSize.small,
                    textDecoration: 'underline',
                    transition: `background-color ${TRANSITIONS.fast}`,
                } }, "Clear all filters"))))));
};
