import { jsxs, jsx } from 'react/jsx-runtime';
import { useState, useCallback, useMemo, forwardRef, useId } from 'react';
import { c as cn } from './utils-DdHUxIdC.js';
import { Field, FieldLabel, FieldContent } from './primitives/Field.js';
import { X } from './x-_o2T3n6D.js';

const EMAIL_REGEX = /^[A-Z0-9._%+-]+@[A-Z0-9-]+(?:\.[A-Z0-9-]+)*\.[A-Z]{2,}$/i;
const UNSTRICT_EMAIL_REGEX = /(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))/g;
const EMAIL_SEPARATION_REGEX = /[^\s,]+/g;

const formatEmailInputOption = (email) => ({
    label: email,
    value: email,
    valid: EMAIL_REGEX.test(email),
});
const pruneDuplicates = (existing, newEmailStrings) => {
    const seen = new Set(existing.map(e => e.value.toLowerCase()));
    const duplicates = [];
    const added = [];
    for (const emailStr of newEmailStrings) {
        const lower = emailStr.toLowerCase();
        if (seen.has(lower)) {
            duplicates.push(emailStr);
        }
        else {
            seen.add(lower);
            added.push(formatEmailInputOption(emailStr));
        }
    }
    return { uniqueEmails: [...existing, ...added], duplicates };
};
const filterValidEmails = (emails) => emails.filter(email => email.valid);
const pluralizeEmail = (count) => count === 1 ? "email" : "emails";
const formatDuplicateWarning = (duplicates) => {
    const count = duplicates.length;
    return `Removed ${count} duplicate ${pluralizeEmail(count)} from the list: ${duplicates.join(", ")}`;
};

function useMultiEmailState(props) {
    const { value = [], onChange, onBlur, visibleEmailsCount = 3, isAlwaysExpanded = false, counter, filterInvalidEmails, } = props;
    const [inputValue, setInputValue] = useState("");
    const [isFocused, setIsFocused] = useState(false);
    const [duplicateEmails, setDuplicateEmails] = useState([]);
    const addEmails = useCallback((input) => {
        const trimmed = input.trim();
        if (!trimmed)
            return;
        UNSTRICT_EMAIL_REGEX.lastIndex = 0;
        EMAIL_SEPARATION_REGEX.lastIndex = 0;
        const emailMatches = trimmed.match(UNSTRICT_EMAIL_REGEX) ||
            trimmed.match(EMAIL_SEPARATION_REGEX) ||
            [];
        if (emailMatches.length === 0)
            return;
        const { uniqueEmails, duplicates } = pruneDuplicates(value, emailMatches);
        onChange?.(uniqueEmails);
        setDuplicateEmails(duplicates);
        setInputValue("");
    }, [value, onChange]);
    const handleKeyDown = useCallback((event) => {
        if (!inputValue && event.key === "Backspace" && value.length > 0) {
            onChange?.(value.slice(0, -1));
            return;
        }
        if (!inputValue)
            return;
        if (["Enter", "Tab", ",", " "].includes(event.key)) {
            addEmails(inputValue);
            event.preventDefault();
            event.stopPropagation();
        }
    }, [inputValue, value, onChange, addEmails]);
    const handlePaste = useCallback((event) => {
        const text = event.clipboardData.getData("text");
        if (!text)
            return;
        event.preventDefault();
        addEmails(text);
    }, [addEmails]);
    const handleBlur = useCallback(() => {
        if (inputValue) {
            addEmails(inputValue);
        }
        else {
            onBlur?.();
        }
        setIsFocused(false);
        setDuplicateEmails([]);
    }, [inputValue, addEmails, onBlur]);
    const handleFocus = useCallback(() => setIsFocused(true), []);
    const handleChipRemove = useCallback((emailValue) => onChange?.(value.filter(e => e.value !== emailValue)), [value, onChange]);
    const handleFilterInvalidEmails = useCallback(() => onChange?.(filterValidEmails(value)), [value, onChange]);
    const validCount = useMemo(() => value.filter(e => e.valid).length, [value]);
    const isCounterVisible = !!counter &&
        (typeof counter === "boolean" ||
            !counter.startsFrom ||
            validCount >= counter.startsFrom);
    const shouldCollapse = !isAlwaysExpanded && !isFocused && value.length > visibleEmailsCount;
    const visibleEmails = shouldCollapse
        ? value.slice(0, visibleEmailsCount)
        : value;
    const hiddenCount = shouldCollapse ? value.length - visibleEmailsCount : 0;
    const isFilterLinkVisible = !!filterInvalidEmails && value.length > validCount;
    return {
        inputValue,
        setInputValue,
        isFocused,
        duplicateEmails,
        handleKeyDown,
        handlePaste,
        handleBlur,
        handleFocus,
        handleChipRemove,
        handleFilterInvalidEmails,
        isCounterVisible,
        validCount,
        visibleEmails,
        hiddenCount,
        isFilterLinkVisible,
    };
}

const CHIP_BASE = "flex h-[calc(--spacing(5.25))] w-fit items-center justify-center gap-1 rounded-sm bg-muted px-1.5 text-xs font-medium whitespace-nowrap text-foreground";
const CHIP_INVALID = "border border-destructive text-destructive bg-destructive/10";
const CHIPS_CONTAINER = "flex min-h-8 flex-wrap items-center gap-1 rounded-lg border border-input bg-transparent bg-clip-padding px-2.5 py-1 text-sm transition-colors focus-within:border-ring focus-within:ring-3 focus-within:ring-ring/50";
const CHIPS_ERROR = "border-destructive ring-3 ring-destructive/20 dark:border-destructive/50 dark:ring-destructive/40";
const MultiEmailInput = forwardRef((props, ref) => {
    const { label, placeholder = "", helpText, error, disabled = false, required = false, maxHeight = 200, counter, filterInvalidEmails, prefix, suffix, labelProps, className, } = props;
    const id = useId();
    const s = useMultiEmailState(props);
    return (jsxs(Field, { className: cn("flex flex-col gap-1.5", className), children: [(label || s.isCounterVisible) && (jsxs("div", { className: "flex items-center justify-between", children: [label && (jsxs(FieldLabel, { htmlFor: id, ...labelProps, children: [label, required && (jsx("span", { "aria-hidden": "true", className: "text-destructive", children: " *" }))] })), s.isCounterVisible && (jsxs("span", { className: "text-xs text-muted-foreground", children: [s.validCount, " ", typeof counter === "object" && counter?.label
                                ? counter.label
                                : pluralizeEmail(s.validCount)] }))] })), jsxs("div", { className: cn(CHIPS_CONTAINER, !!error && CHIPS_ERROR, disabled && "pointer-events-none opacity-50"), style: { maxHeight: `${maxHeight}px`, overflowY: "auto" }, children: [prefix && jsx("div", { className: "shrink-0", children: prefix }), s.visibleEmails.map(email => (jsxs("span", { className: cn(CHIP_BASE, !email.valid && CHIP_INVALID), children: [email.label, !disabled && (jsx("button", { type: "button", tabIndex: -1, className: "-ms-0.5 rounded-xs opacity-50 hover:opacity-100", onMouseDown: e => e.preventDefault(), onClick: () => s.handleChipRemove(email.value), "aria-label": `Remove ${email.label}`, children: jsx(X, { className: "size-3 pointer-events-none" }) }))] }, email.value))), s.hiddenCount > 0 && (jsxs("span", { className: "flex h-[calc(--spacing(5.25))] items-center rounded-sm bg-secondary px-1.5 text-xs font-medium text-secondary-foreground", children: ["+", s.hiddenCount, " more"] })), jsx("input", { ref: ref, id: id, type: "text", value: s.inputValue, onChange: e => s.setInputValue(e.target.value), onKeyDown: s.handleKeyDown, onPaste: s.handlePaste, onFocus: s.handleFocus, onBlur: s.handleBlur, placeholder: props.value?.length ? "" : placeholder, disabled: disabled, className: "min-w-16 flex-1 bg-transparent text-sm outline-none placeholder:text-muted-foreground" }), suffix && jsx("div", { className: "shrink-0", children: suffix })] }), jsxs(FieldContent, { children: [!!error && (jsxs("p", { className: "text-[0.8rem] text-destructive", children: [error, s.isFilterLinkVisible && (jsx("button", { type: "button", className: "ml-1 cursor-pointer font-semibold underline", onClick: s.handleFilterInvalidEmails, children: filterInvalidEmails?.label ??
                                    "Click here to remove invalid emails." }))] })), !!helpText && (jsx("p", { className: "text-[0.8rem] text-muted-foreground", children: helpText })), s.duplicateEmails.length > 0 && (jsx("p", { className: "text-[0.8rem] text-amber-600 dark:text-amber-400", children: formatDuplicateWarning(s.duplicateEmails) }))] })] }));
});
MultiEmailInput.displayName = "MultiEmailInput";

export { MultiEmailInput as M };
//# sourceMappingURL=MultiEmailInput-SCTYovtX.js.map
