import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
// (C) 2025-2026 GoodData Corporation
import { useId, useMemo, useRef, useState } from "react";
import { bem } from "../@utils/bem.js";
import { UiButton } from "../UiButton/UiButton.js";
import { UiCombobox } from "../UiCombobox/UiCombobox.js";
import { UiComboboxInput } from "../UiCombobox/UiComboboxInput.js";
import { UiComboboxList } from "../UiCombobox/UiComboboxList.js";
import { UiComboboxListItem, UiComboboxListItemCreatableLabel, UiComboboxListItemLabel, } from "../UiCombobox/UiComboboxListItem.js";
import { UiComboboxPopup } from "../UiCombobox/UiComboboxPopup.js";
import { UiPopover } from "../UiPopover/UiPopover.js";
import { UiTooltip } from "../UiTooltip/UiTooltip.js";
import { useResponsiveTags } from "./hooks/useResponsiveTags.js";
import { useTagsInteractions } from "./interactions.js";
import { UiTag } from "./UiTag.js";
const { b, e } = bem("gd-ui-kit-tags");
const defaultAccessibilityConfig = {};
/**
 * @internal
 */
export function UiTags({ tags, tagOptions, addLabel = "Add tag", nameLabel = "Name", cancelLabel = "Cancel", closeLabel = "Close", saveLabel = "Save", noTagsLabel = "No tags", moreLabel = "More tags", removeLabel = "Remove", creatableLabel = "(Create new)", mode = "single-line", size = "small", canDeleteTags = true, canCreateTag = true, readOnly = false, onTagClick, onTagAdd = () => { }, onTagRemove = () => { }, accessibilityConfig = defaultAccessibilityConfig, renderAddButton, }) {
    const inputRef = useRef(null);
    const [popupOpen, setPopupOpen] = useState(false);
    const popupId = useId();
    const isDeletable = canDeleteTags && !readOnly;
    // A custom add-button slot takes precedence over the built-in create-tag combobox.
    const hasCustomAddButton = !!renderAddButton && !readOnly;
    const isAddable = canCreateTag && !readOnly && !hasCustomAddButton;
    const { rootRef, showedTags, hiddenTags, tagsContainerRef, hiddenTagsContainerRef, tooltipTagsContainerRef, addButtonRef, allContainerRef, tooltipWidth, availableWidth, lastAvailableWidth, setTooltipContainer, } = useResponsiveTags(tags, mode, [canCreateTag, canDeleteTags, readOnly, hasCustomAddButton]);
    const items = [...showedTags, hiddenTags];
    const { interactionState, onAddOpen, onAddClose, onMoreOpen, onMoreClose, tag, setTag, onTagClickHandler, onTagRemoveHandler, onTagAddHandler, } = useTagsInteractions(tagsContainerRef, tooltipTagsContainerRef, showedTags, hiddenTags, onTagAdd, onTagRemove, onTagClick);
    const [morePopoverOpen, setMorePopoverOpen] = useState(false);
    const morePopoverId = useId();
    const groupLabelId = useId();
    const hasTagClickHandler = onTagClick !== undefined;
    const groupLabelledBy = accessibilityConfig?.ariaLabelledBy ?? groupLabelId;
    const groupLabelText = accessibilityConfig?.ariaLabel ?? (tags.length === 1 ? "Tags, 1" : `Tags, ${tags.length}`);
    const comboboxOptions = useMemo(() => {
        if (!tagOptions) {
            return [];
        }
        const tagIds = new Set(tags.map((tag) => tag.id));
        return tagOptions
            .filter((tagOption) => !tagIds.has(tagOption.id))
            .map((tagOption) => ({ id: tagOption.id, label: tagOption.label }));
    }, [tagOptions, tags]);
    return (_jsxs("div", { ref: rootRef, className: b({ readOnly, mode }), "aria-labelledby": groupLabelledBy, "aria-describedby": accessibilityConfig?.ariaDescribedBy, role: accessibilityConfig?.role ?? "group", children: [accessibilityConfig?.ariaLabelledBy ? null : (_jsx("span", { className: "sr-only", id: groupLabelId, children: groupLabelText })), _jsx("div", { className: e("shadow-container"), ref: allContainerRef, children: tags.map((tag) => {
                    return (_jsx(UiTag, { tag: tag, isDeletable: isDeletable, size: size }, getKey(tag, isDeletable, readOnly)));
                }) }), _jsxs("div", { className: e("tags-container"), ref: tagsContainerRef, children: [items.map((tag, i) => {
                        if (Array.isArray(tag)) {
                            if (hiddenTags.length === 0) {
                                return null;
                            }
                            return (_jsx("div", { className: e("hidden-tags"), onClick: (e) => {
                                    e.stopPropagation();
                                    e.preventDefault();
                                }, children: hiddenTags.length > 0 ? (_jsx(UiPopover, { id: morePopoverId, onOpen: () => {
                                        setMorePopoverOpen(true);
                                        onMoreOpen();
                                    }, onClose: () => {
                                        setMorePopoverOpen(false);
                                        onMoreClose();
                                    }, enableFocusTrap: true, initialFocus: tooltipTagsContainerRef, returnFocusTo: hiddenTagsContainerRef, anchor: _jsx(UiButton, { label: `+${hiddenTags.length}`, size: "small", variant: "tertiary", accessibilityConfig: {
                                            ariaLabel: moreLabel,
                                            ariaExpanded: morePopoverOpen,
                                            ariaHaspopup: "dialog",
                                            ariaControls: morePopoverId,
                                        }, ref: (ref) => {
                                            hiddenTagsContainerRef.current = ref;
                                        } }), width: 300, title: moreLabel, content: () => (_jsx("div", { className: e("tags-more-tooltip"), ref: (ref) => {
                                            tooltipTagsContainerRef.current = ref;
                                            setTooltipContainer(ref);
                                        }, children: hiddenTags.map((tag, i) => {
                                            return (_jsx(UiTag, { tag: tag, deleteLabel: removeLabel, isDeletable: isDeletable, isDisabled: readOnly, size: size, maxWidth: tooltipWidth, onDelete: onTagRemoveHandler, onClick: hasTagClickHandler
                                                    ? onTagClickHandler
                                                    : undefined }, i));
                                        }) })), footer: ({ onClose }) => (_jsx(_Fragment, { children: _jsx(UiButton, { ref: (ref) => {
                                                interactionState.current.close = ref;
                                            }, label: closeLabel, variant: "secondary", onClick: () => {
                                                onClose();
                                            } }) })) })) : null }, i));
                        }
                        return (_jsx(UiTag, { tag: tag, isDeletable: isDeletable, isDisabled: readOnly, deleteLabel: removeLabel, size: size, onDelete: onTagRemoveHandler, onClick: hasTagClickHandler ? onTagClickHandler : undefined, maxWidth: i === showedTags.length - 1 ? lastAvailableWidth : availableWidth }, getKey(tag, isDeletable, readOnly)));
                    }), hasCustomAddButton ? (_jsx("div", { className: e("add-button"), ref: addButtonRef, onClick: (e) => {
                            e.stopPropagation();
                            e.preventDefault();
                        }, onKeyDown: (e) => {
                            e.stopPropagation();
                        }, children: renderAddButton?.() })) : isAddable ? (_jsx("div", { className: e("add-button"), ref: addButtonRef, onClick: (e) => {
                            e.stopPropagation();
                            e.preventDefault();
                        }, children: _jsx(UiPopover, { id: popupId, onOpen: () => {
                                onAddOpen();
                                setPopupOpen(true);
                            }, onClose: () => {
                                setTag("");
                                onAddClose();
                                setPopupOpen(false);
                            }, enableFocusTrap: true, anchor: _jsx(UiTooltip, { content: addLabel, triggerBy: ["hover", "focus"], anchorWrapperStyles: { display: "flex", alignItems: "center" }, anchor: _jsx(UiButton, { label: showedTags.length > 0 ? "" : addLabel, accessibilityConfig: {
                                        ariaHaspopup: true,
                                        ariaControls: popupId,
                                        ariaLabel: addLabel,
                                        ariaExpanded: popupOpen,
                                    }, size: "small", iconBefore: "plus", variant: "tertiary", ref: (ref) => {
                                        interactionState.current.add = ref;
                                    } }) }), title: addLabel, initialFocus: inputRef, content: ({ onClose }) => (_jsxs(UiCombobox, { options: comboboxOptions, value: tag, onValueChange: setTag, creatable: true, children: [
                                    _jsx(UiComboboxInput, { ref: (node) => {
                                            inputRef.current = node;
                                            interactionState.current.input = node;
                                        }, name: "add-input", accessibilityConfig: { ariaLabel: nameLabel }, onKeyDown: (event) => {
                                            if (event.isDefaultPrevented()) {
                                                return;
                                            }
                                            if (event.key === "Enter") {
                                                onTagAddHandler();
                                                onClose();
                                            }
                                        } }), _jsx(UiComboboxPopup, { children: _jsx(UiComboboxList, { children: (option, index) => (_jsxs(UiComboboxListItem, { option: option, index: index, children: [
                                                    _jsx(UiComboboxListItemLabel, { children: option.label }), option.creatable ? (_jsx(UiComboboxListItemCreatableLabel, { children: creatableLabel })) : null] }, option.id)) }) })
                                ] })), footer: ({ onClose }) => (_jsxs(_Fragment, { children: [
                                    _jsx(UiButton, { label: cancelLabel, variant: "secondary", onClick: onClose, ref: (ref) => {
                                            interactionState.current.close = ref;
                                        } }), _jsx(UiButton, { label: saveLabel, isDisabled: !tag, variant: "primary", onClick: () => {
                                            onTagAddHandler();
                                            onClose();
                                        }, ref: (ref) => {
                                            interactionState.current.save = ref;
                                        } })
                                ] })) }) })) : null, !isAddable && !hasCustomAddButton && tags.length === 0 ? (_jsx("div", { className: e("empty-state"), children: noTagsLabel })) : null] })
        ] }));
}
function getKey(tag, isDeletable, readOnly) {
    return [tag.id, tag.isDeletable, isDeletable, readOnly].filter(Boolean).join("-");
}
