import { jsxs, jsx } from 'react/jsx-runtime';
import React__default, { useState, useMemo, useCallback } from 'react';
import { AnimatePresence, motion } from 'motion/react';
import { XMarkIcon } from '@heroicons/react/24/outline';
import { UserIcon } from '@heroicons/react/16/solid';
import { cn } from '../../../utils/cn.js';
import { Avatar } from '../Avatar/Avatar.js';
import { animationTiming, dismissVariants, badgeVariants, dismissButtonVariants, dotVariants } from './Badge.animations.js';
import { badgeTheme } from './Badge.theme.js';

// Helper to determine whether we should animate (Storybook can disable animations globally)
const getShouldAnimate = () => {
    if (typeof window === "undefined")
        return true;
    if (window.__STORYBOOK_DISABLE_ANIMATIONS__)
        return false;
    try {
        return !window.matchMedia("(prefers-reduced-motion: reduce)").matches;
    }
    catch (_a) {
        return true;
    }
};
/**
 * Badge component for displaying status, labels, or counters.
 *
 * @component
 * @example
 * ```tsx
 * <Badge variant="primary" size="md" pill>New Feature</Badge>
 * <Badge variant="success" withDot>Ready</Badge>
 * <Badge dismissible onDismiss={handleDismiss}>Removable</Badge>
 * ```
 */
const Badge = React__default.memo(React__default.forwardRef(({ children, variant = "filled", color = "primary", size = "md", pill = false, withDot = false, iconStart, avatar, dismissible = false, onDismiss, disabled = false, maxWidth, className, theme: customTheme = {}, onClick, darkMode = false, ...props }, ref) => {
    var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q;
    // State management
    const [isVisible, setIsVisible] = useState(true);
    const shouldAnimate = useMemo(getShouldAnimate, []);
    // Development-only warnings
    if (process.env.NODE_ENV !== "production") {
        if (dismissible && !onDismiss) {
            console.warn("[Badge]: onDismiss prop is required when dismissible is true");
        }
        if (avatar && iconStart) {
            console.warn("[Badge]: Both avatar and iconStart provided. Avatar takes precedence.");
        }
    }
    // Handle dismiss button click
    const handleDismiss = useCallback((e) => {
        e.stopPropagation();
        setIsVisible(false);
        // Delay the onDismiss call until after the animation
        setTimeout(() => {
            onDismiss === null || onDismiss === void 0 ? void 0 : onDismiss(e);
        }, animationTiming.dismissDelay);
    }, [onDismiss]);
    // Handle badge click
    const handleClick = useCallback((e) => {
        if (disabled)
            return;
        onClick === null || onClick === void 0 ? void 0 : onClick(e);
    }, [onClick, disabled]);
    // Merge default theme with custom theme overrides
    const theme = {
        ...badgeTheme,
        ...customTheme,
        variants: {
            ...badgeTheme.variants,
            ...customTheme.variants,
        },
        variantColors: {
            filled: {
                ...(_a = badgeTheme.variantColors) === null || _a === void 0 ? void 0 : _a.filled,
                ...(_b = customTheme.variantColors) === null || _b === void 0 ? void 0 : _b.filled,
            },
            outline: {
                ...(_c = badgeTheme.variantColors) === null || _c === void 0 ? void 0 : _c.outline,
                ...(_d = customTheme.variantColors) === null || _d === void 0 ? void 0 : _d.outline,
            },
            soft: {
                ...(_e = badgeTheme.variantColors) === null || _e === void 0 ? void 0 : _e.soft,
                ...(_f = customTheme.variantColors) === null || _f === void 0 ? void 0 : _f.soft,
            },
        },
        sizes: {
            ...badgeTheme.sizes,
            ...customTheme.sizes,
        },
        pillSizes: {
            ...badgeTheme.pillSizes,
            ...customTheme.pillSizes,
        },
        iconSizes: {
            ...badgeTheme.iconSizes,
            ...customTheme.iconSizes,
        },
        avatarSizes: {
            ...badgeTheme.avatarSizes,
            ...customTheme.avatarSizes,
        },
        dismissSizes: {
            ...badgeTheme.dismissSizes,
            ...customTheme.dismissSizes,
        },
        dotColors: {
            ...badgeTheme.dotColors,
            ...customTheme.dotColors,
        },
        states: {
            ...badgeTheme.states,
            ...customTheme.states,
        },
    };
    // Get styles from theme
    const variantStyles = ((_g = theme.variants) === null || _g === void 0 ? void 0 : _g[variant]) || "";
    const colorStyles = ((_j = (_h = theme.variantColors) === null || _h === void 0 ? void 0 : _h[variant]) === null || _j === void 0 ? void 0 : _j[color]) || "";
    const sizeStyle = ((_k = theme.sizes) === null || _k === void 0 ? void 0 : _k[size]) || "";
    const shapeStyle = pill
        ? "rounded-full"
        : "rounded-[var(--badge-radius)]";
    const dotColorStyle = ((_l = theme.dotColors) === null || _l === void 0 ? void 0 : _l[color]) || "";
    // Build base styles with all states
    const isInteractive = dismissible;
    const baseStyles = cn(theme.baseStyle, shapeStyle, variantStyles, colorStyles, sizeStyle, pill && ((_m = theme.pillSizes) === null || _m === void 0 ? void 0 : _m[size]), isInteractive && "cursor-pointer", disabled && ((_o = theme.states) === null || _o === void 0 ? void 0 : _o.disabled), darkMode && "dark", className);
    // Create data attributes for styling hooks
    const dataAttributes = {
        "data-variant": variant,
        "data-color": color,
        "data-size": size,
        "data-state": isVisible ? "visible" : "hidden",
        "data-pill": pill ? "true" : "false",
        "data-with-dot": withDot ? "true" : "false",
        "data-dismissible": dismissible ? "true" : "false",
        "data-disabled": disabled ? "true" : "false",
        "data-interactive": isInteractive ? "true" : "false",
    };
    // Render left content (priority: avatar → iconStart → dot)
    const renderLeftContent = () => {
        var _a, _b, _c;
        if (avatar) {
            // Apply negative margin for overlap effect (scales with badge size)
            const avatarMargin = pill
                ? {
                    sm: "-ml-1.5",
                    md: "-ml-1.5",
                }[size]
                : {
                    sm: "-ml-1.5",
                    md: "-ml-1",
                }[size];
            return (jsx("span", { className: cn("inline-flex items-center justify-center shrink-0 overflow-hidden", (_a = theme.avatarSizes) === null || _a === void 0 ? void 0 : _a[size], avatarMargin, pill ? "rounded-full" : "rounded-md"), children: jsx(Avatar, { src: avatar.src, name: avatar.name, fallback: (_b = avatar.fallback) !== null && _b !== void 0 ? _b : jsx(UserIcon, { className: "size-2.5" }), initialsCount: avatar.initialsCount, size: "xs", className: cn("!size-full border-0", pill ? "rounded-full" : "rounded-md ring-0") }) }));
        }
        if (iconStart) {
            return (jsx("span", { className: cn("inline-flex items-center justify-center flex-shrink-0", (_c = theme.iconSizes) === null || _c === void 0 ? void 0 : _c[size]), "aria-hidden": "true", children: iconStart }));
        }
        if (withDot) {
            if (shouldAnimate) {
                return (jsx(motion.span, { className: cn("badge-dot rounded-full shrink-0 size-1.5 ring-2 ring-current/20", dotColorStyle), variants: dotVariants, "aria-hidden": "true" }));
            }
            return (jsx("span", { className: cn("badge-dot rounded-full shrink-0 size-1.5", dotColorStyle), "aria-hidden": "true" }));
        }
        return null;
    };
    if (!shouldAnimate) {
        // Spread props directly — Badge only receives HTMLSpanElement attributes
        const restHtmlProps = props;
        // Non-animated render for Storybook or reduced-motion environments
        return isVisible ? (jsxs("span", { ref: ref, className: baseStyles, onClick: handleClick, "aria-disabled": disabled || undefined, ...dataAttributes, ...restHtmlProps, children: [renderLeftContent(), jsx("span", { className: cn("badge-content", maxWidth && "truncate"), style: maxWidth
                        ? {
                            maxWidth: typeof maxWidth === "number"
                                ? `${maxWidth}px`
                                : maxWidth,
                        }
                        : undefined, children: children }), dismissible && (jsx("button", { type: "button", onClick: handleDismiss, className: "badge-dismiss-btn -ml-1 -mr-1 rounded-full p-0.5 cursor-pointer", "aria-label": "Dismiss", disabled: disabled, children: jsx(XMarkIcon, { className: cn("badge-dismiss-icon", (_p = theme.dismissSizes) === null || _p === void 0 ? void 0 : _p[size]), "aria-hidden": "true" }) }))] })) : null;
    }
    return (jsx(AnimatePresence, { mode: "wait", children: isVisible && (jsxs(motion.span, { ref: ref, className: baseStyles, onClick: handleClick, "aria-disabled": disabled || undefined, variants: dismissible ? dismissVariants : badgeVariants, initial: "initial", animate: "animate", exit: "exit", ...dataAttributes, ...props, children: [renderLeftContent(), jsx("span", { className: cn("badge-content", maxWidth && "truncate"), style: maxWidth
                        ? {
                            maxWidth: typeof maxWidth === "number"
                                ? `${maxWidth}px`
                                : maxWidth,
                        }
                        : undefined, children: children }), dismissible && (jsx(motion.button, { type: "button", onClick: handleDismiss, className: "badge-dismiss-btn -ml-1 -mr-1 rounded-full p-0.5 cursor-pointer", "aria-label": "Dismiss", disabled: disabled, variants: dismissButtonVariants, initial: "initial", whileHover: "hover", whileTap: "tap", children: jsx(XMarkIcon, { className: cn("badge-dismiss-icon", (_q = theme.dismissSizes) === null || _q === void 0 ? void 0 : _q[size]), "aria-hidden": "true", strokeWidth: 2 }) }))] })) }));
}));
Badge.displayName = "Badge";

export { Badge };
