import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
// (C) 2026 GoodData Corporation
import { useEffect, useState } from "react";
import cx from "classnames";
import { defineMessages, useIntl } from "react-intl";
import { CSV_DELIMITER_PRESETS, } from "@gooddata/sdk-model";
import { ValidationContextStore, createInvalidDatapoint, createInvalidNode, useValidationContextValue, } from "@gooddata/sdk-ui";
import { UiDropdown } from "../@ui/UiDropdown/UiDropdown.js";
import { UiMenu } from "../@ui/UiMenu/UiMenu.js";
import { DropdownButton } from "../Dropdown/DropdownButton.js";
import { Input } from "../Form/Input.js";
import { useIdPrefixed } from "../utils/useId.js";
const DEFAULT_MENU_MIN_WIDTH = 260;
const messages = defineMessages({
    optionComma: { id: "csvDelimiterPicker.option.comma" },
    optionSemicolon: { id: "csvDelimiterPicker.option.semicolon" },
    optionPipe: { id: "csvDelimiterPicker.option.pipe" },
    optionTab: { id: "csvDelimiterPicker.option.tab" },
    optionCustom: { id: "csvDelimiterPicker.option.custom" },
    customInput: { id: "csvDelimiterPicker.customInput" },
    menuLabel: { id: "csvDelimiterPicker.menuLabel" },
    errorPrefix: { id: "csvDelimiterPicker.validation.errorPrefix" },
    validationSingleCharacter: { id: "csvDelimiterPicker.validation.singleCharacter" },
    validationUnsupported: { id: "csvDelimiterPicker.validation.unsupported" },
});
const getPresetLabels = (intl) => ({
    comma: intl.formatMessage(messages.optionComma),
    semicolon: intl.formatMessage(messages.optionSemicolon),
    pipe: intl.formatMessage(messages.optionPipe),
    tab: intl.formatMessage(messages.optionTab),
    custom: intl.formatMessage(messages.optionCustom),
});
const getMenuItems = (presetLabels) => {
    const items = [];
    let id;
    for (id in CSV_DELIMITER_PRESETS) {
        items.push({
            type: "interactive",
            id,
            stringTitle: presetLabels[id],
            data: id,
        });
    }
    items.push({
        type: "interactive",
        id: "custom",
        stringTitle: presetLabels.custom,
        data: "custom",
    });
    return items;
};
const getButtonLabel = (presetLabels, selectedPreset) => {
    const label = presetLabels[selectedPreset];
    const preset = selectedPreset === "custom" ? undefined : CSV_DELIMITER_PRESETS[selectedPreset];
    return preset ? `${label} (${preset.previewSymbol})` : label;
};
function CsvDelimiterMenuItem({ item, isFocused }) {
    const preset = item.data === "custom" ? undefined : CSV_DELIMITER_PRESETS[item.data];
    return (_jsx("div", { className: cx("gd-ui-kit-menu__item", {
            "gd-ui-kit-menu__item--isFocused": isFocused,
            "gd-ui-kit-menu__item--isSelected": !!item.isSelected,
        }), children: _jsxs("span", { className: "gd-csv-delimiter-picker-label", children: [
                _jsx("span", { children: item.stringTitle }), preset ? (_jsxs("span", { className: "gd-csv-delimiter-picker-preview", "aria-hidden": "true", children: [" (", _jsx("span", { className: "gd-csv-delimiter-picker-preview-char", children: preset.previewSymbol }), ")"] })) : null] }) }));
}
/**
 * Reusable CSV delimiter preset picker with dropdown, custom input, and validation.
 *
 * This is a controlled component — the consumer manages state via
 * `getCsvDelimiterState` from `@gooddata/sdk-model` and passes it through props.
 *
 * @internal
 */
export function CsvDelimiterPicker({ value, onChange, validationError, label, onEnterKeyPress, layout = "column", }) {
    const intl = useIntl();
    const { selectedPreset, customDelimiter } = value;
    const buttonId = useIdPrefixed("csv-delimiter-button");
    const errorId = useIdPrefixed("csv-delimiter-error");
    const [isCustomInputDirty, setIsCustomInputDirty] = useState(false);
    const showInlineError = Boolean(validationError) && isCustomInputDirty;
    const errorPrefix = intl.formatMessage(messages.errorPrefix);
    const validationErrorMessage = validationError
        ? validationError === "singleCharacter"
            ? intl.formatMessage(messages.validationSingleCharacter)
            : intl.formatMessage(messages.validationUnsupported)
        : undefined;
    const validationContextValue = useValidationContextValue(createInvalidNode());
    const { setInvalidDatapoints } = validationContextValue;
    // Sync validation errors to ValidationContextStore so the submit button
    // in ConfirmDialogBase always announces them via aria-describedby —
    // when the user focuses the submit button, they should hear why the form
    // can't be submitted, regardless of whether the input is dirty yet.
    useEffect(() => {
        setInvalidDatapoints(() => validationErrorMessage
            ? [
                createInvalidDatapoint({
                    id: errorId,
                    message: `${errorPrefix} ${validationErrorMessage}`,
                }),
            ]
            : []);
    }, [validationErrorMessage, errorPrefix, errorId, setInvalidDatapoints]);
    const presetLabels = getPresetLabels(intl);
    const menuItems = getMenuItems(presetLabels);
    const customInputLabel = intl.formatMessage(messages.customInput);
    const menuAriaLabel = intl.formatMessage(messages.menuLabel);
    return (_jsxs(ValidationContextStore, { value: validationContextValue, children: [label ? _jsx("label", { htmlFor: buttonId, children: label }) : null, _jsxs("div", { className: cx("gd-csv-delimiter-picker-controls", {
                    "gd-csv-delimiter-picker-controls--column": layout === "column",
                    "gd-csv-delimiter-picker-controls--row": layout === "row",
                }), children: [_jsx(UiDropdown, { renderButton: ({ isOpen, toggleDropdown, ref, dropdownId }) => (_jsx(DropdownButton, { id: buttonId, className: "s-csv-delimiter-dropdown", value: getButtonLabel(presetLabels, selectedPreset), isOpen: isOpen, onClick: toggleDropdown, buttonRef: ref, dropdownId: dropdownId, accessibilityConfig: {
                                ...(label ? {} : { ariaLabel: menuAriaLabel }),
                                popupType: "listbox",
                            }, isFullWidth: layout === "column" })), renderBody: ({ closeDropdown, ariaAttributes }) => (_jsx(UiMenu, { items: menuItems.map((item) => ({
                                ...item,
                                isSelected: selectedPreset === item.data,
                            })), itemDataTestId: (item) => `s-csv-delimiter-${item.id}`, onSelect: (item) => {
                                setIsCustomInputDirty(false);
                                onChange({ selectedPreset: item.data, customDelimiter });
                            }, onClose: closeDropdown, shouldCloseOnSelect: true, InteractiveItem: CsvDelimiterMenuItem, ariaAttributes: {
                                ...ariaAttributes,
                                "aria-label": menuAriaLabel,
                            }, minWidth: DEFAULT_MENU_MIN_WIDTH })), autofocusOnOpen: true, fullWidthButton: layout === "column", closeOnEscape: true, accessibilityConfig: {
                            triggerRole: "button",
                            popupRole: "listbox",
                        } }), selectedPreset === "custom" ? (_jsxs("div", { className: "gd-csv-delimiter-picker-custom-field", children: [
                            _jsx(Input, { className: "gd-csv-delimiter-picker-custom-input s-csv-delimiter-custom-input", isSmall: true, value: customDelimiter, onChange: (value) => {
                                    setIsCustomInputDirty(true);
                                    onChange({ selectedPreset, customDelimiter: String(value) });
                                }, hasError: showInlineError, autocomplete: "off", onEnterKeyPress: onEnterKeyPress, accessibilityConfig: {
                                    ariaLabel: customInputLabel,
                                    ariaInvalid: showInlineError,
                                    ariaDescribedBy: showInlineError ? errorId : undefined,
                                } }), validationErrorMessage ? (_jsxs("div", { id: errorId, className: cx("gd-csv-delimiter-picker-error", {
                                    "sr-only": !showInlineError,
                                }), children: [errorPrefix, " ", validationErrorMessage] })) : null] })) : null] })
        ] }));
}
