"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const jsx_runtime_1 = require("react/jsx-runtime");
const React = tslib_1.__importStar(require("react"));
const icons_1 = require("@gravity-ui/icons");
const uikit_1 = require("@gravity-ui/uikit");
const cn_1 = require("../../utils/cn.js");
const fields_1 = require("../../utils/fields.js");
const Base_1 = tslib_1.__importDefault(require("../Base/Base.js"));
const Fields_1 = tslib_1.__importDefault(require("../Fields/Fields.js"));
const SectionOpenContext_1 = require("./SectionOpenContext.js");
const b = (0, cn_1.formGeneratorCn)('section');
const makeRowKey = () => typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function'
    ? crypto.randomUUID()
    : `row-${Math.random().toString(36).slice(2, 11)}`;
const Section = ({ title, opened, fields, when, content, onUpdate, className, index, withAddButton, itemTitle, itemView, }) => {
    const isGroupMode = index !== undefined;
    const parentContext = React.useContext(SectionOpenContext_1.SectionOpenContext);
    const nestingLevel = parentContext?.nestingLevel ?? 0;
    // --- Static section state ---
    const [isOpened, setOpened] = React.useState(opened);
    const [confirmDialogOpen, setConfirmDialogOpen] = React.useState(false);
    const hasData = (0, fields_1.sectionHasContentData)(fields, content);
    const showArrowTogler = hasData || isOpened;
    const prevHasDataRef = React.useRef(null);
    React.useEffect(() => {
        if (isGroupMode)
            return;
        const hadData = prevHasDataRef.current;
        if (hadData === true && !hasData) {
            setOpened(false);
        }
        prevHasDataRef.current = hasData;
    }, [hasData, isGroupMode]);
    const handleConfirmClear = () => {
        if (onUpdate) {
            (0, fields_1.clearSectionFormContent)(fields, onUpdate);
        }
        setConfirmDialogOpen(false);
        setOpened(false);
    };
    // --- Group mode state ---
    const [rowKeys, setRowKeys] = React.useState([]);
    const nameWithIndexName = React.useMemo(() => (isGroupMode && index ? (0, fields_1.findNameWithIndexName)(fields, index) : undefined), [fields, index, isGroupMode]);
    const arrayPath = React.useMemo(() => nameWithIndexName && index
        ? (0, fields_1.getArrayPathForNameWithIndexName)(nameWithIndexName, index)
        : undefined, [nameWithIndexName, index]);
    const valuesInside = React.useMemo(() => (arrayPath ? (0, fields_1.getValueByPath)(content, arrayPath) : undefined), [arrayPath, content]);
    const valuesInsideLength = Array.isArray(valuesInside) ? valuesInside.length : 0;
    React.useEffect(() => {
        if (!isGroupMode)
            return;
        if (!nameWithIndexName || !arrayPath) {
            setRowKeys((prev) => (prev.length === 0 ? [makeRowKey()] : prev));
            return;
        }
        if (!content) {
            return;
        }
        setRowKeys((prev) => {
            if (prev.length === valuesInsideLength) {
                return prev;
            }
            if (valuesInsideLength > prev.length) {
                return [
                    ...prev,
                    ...Array.from({ length: valuesInsideLength - prev.length }, makeRowKey),
                ];
            }
            return prev.slice(0, valuesInsideLength);
        });
    }, [content, arrayPath, nameWithIndexName, valuesInside, valuesInsideLength, isGroupMode]);
    const replaceIndex = (i) => fields ? JSON.parse(JSON.stringify(fields).replaceAll(`{{${index}}}`, String(i))) : fields;
    const handleAdd = () => {
        if (arrayPath && onUpdate) {
            const next = Array.isArray(valuesInside) ? [...valuesInside, {}] : [{}];
            onUpdate(arrayPath, next);
            return;
        }
        setRowKeys((prev) => [...prev, makeRowKey()]);
    };
    const deleteItem = (itemIndex) => () => {
        if (!nameWithIndexName || !onUpdate || !index) {
            return;
        }
        const names = (0, fields_1.findAllNames)(replaceIndex(itemIndex));
        const resolvedName = names.find((name) => {
            const splice = (0, fields_1.getSpliceTarget)(nameWithIndexName, name, index);
            return splice !== undefined && splice.itemIndex === itemIndex;
        }) ?? names[0];
        if (!resolvedName) {
            return;
        }
        const spliceTarget = (0, fields_1.getSpliceTarget)(nameWithIndexName, resolvedName, index);
        if (!spliceTarget) {
            return;
        }
        onUpdate(spliceTarget.arrayPath, undefined, { removeArrayItemAt: spliceTarget.itemIndex });
        setRowKeys((prev) => prev.filter((_key, keyIndex) => keyIndex !== itemIndex));
    };
    // --- Group mode render ---
    if (isGroupMode) {
        const hasGroupLabel = Boolean(title);
        const isEmpty = rowKeys.length === 0;
        const isGroupOpen = isOpened ?? true;
        const resolvedItemTitle = (i) => {
            const src = itemTitle || title;
            return src ? src.replaceAll(`{{${index}}}`, String(i)) : undefined;
        };
        const labelTemplate = itemTitle || title;
        const addButtonLabel = labelTemplate
            ? labelTemplate.replaceAll(`{{${index}}}`, String(rowKeys.length))
            : 'Add';
        const renderItem = (rowKey, rowIndex) => {
            const cardTitle = resolvedItemTitle(rowIndex);
            const header = ((0, jsx_runtime_1.jsxs)("div", { className: b('card-header'), children: [cardTitle && ((0, jsx_runtime_1.jsx)(uikit_1.Text, { variant: "subheader-2", className: b('card-title'), children: cardTitle })), (0, jsx_runtime_1.jsx)(uikit_1.Button, { view: "flat", onClick: deleteItem(rowIndex), children: (0, jsx_runtime_1.jsx)(uikit_1.Icon, { width: 16, height: 16, data: icons_1.TrashBin }) })] }));
            const inner = ((0, jsx_runtime_1.jsx)(SectionOpenContext_1.SectionOpenContext.Provider, { value: { isOpen: true, nestingLevel: nestingLevel + 1 }, children: (0, jsx_runtime_1.jsx)(Fields_1.default, { fields: replaceIndex(rowIndex), content: content, onUpdate: onUpdate }) }));
            if (itemView === 'clear') {
                return ((0, jsx_runtime_1.jsxs)("div", { className: b('item-clear'), children: [header, inner] }, rowKey));
            }
            return ((0, jsx_runtime_1.jsxs)(uikit_1.Card, { className: b('card'), children: [header, inner] }, rowKey));
        };
        return ((0, jsx_runtime_1.jsx)(Base_1.default, { when: when, content: content, children: (0, jsx_runtime_1.jsxs)("div", { className: b({ nested: nestingLevel > 0 }, className), children: [hasGroupLabel && ((0, jsx_runtime_1.jsx)("div", { className: b('header'), children: (0, jsx_runtime_1.jsxs)("button", { type: "button", className: b('header-button', { 'with-hover': isEmpty }), onClick: isEmpty ? handleAdd : () => setOpened((prev) => !prev), children: [!isEmpty && ((0, jsx_runtime_1.jsx)(uikit_1.ArrowToggle, { direction: isGroupOpen ? 'top' : 'bottom', className: b('arrow') })), (0, jsx_runtime_1.jsx)(uikit_1.Text, { variant: "subheader-1", color: "hint", className: b('title'), children: title }), isEmpty && (0, jsx_runtime_1.jsx)(icons_1.Plus, { width: 16, height: 16, className: b('plus') })] }) })), (0, jsx_runtime_1.jsx)("div", { className: b('children', {
                            opened: !isEmpty && (!hasGroupLabel || isGroupOpen),
                        }), children: (0, jsx_runtime_1.jsxs)("div", { className: b('children-inner'), children: [rowKeys.map((rowKey, rowIndex) => renderItem(rowKey, rowIndex)), withAddButton && !isEmpty && ((0, jsx_runtime_1.jsxs)(uikit_1.Button, { onClick: handleAdd, children: ["Add ", addButtonLabel] }))] }) })] }) }));
    }
    // --- Static section render ---
    return ((0, jsx_runtime_1.jsx)(Base_1.default, { when: when, content: content, children: (0, jsx_runtime_1.jsxs)(React.Fragment, { children: [(0, jsx_runtime_1.jsxs)("div", { className: b({ opened: isOpened, nested: nestingLevel > 0 }, className), children: [(0, jsx_runtime_1.jsxs)("div", { className: b('header'), children: [(0, jsx_runtime_1.jsxs)("button", { type: "button", className: b('header-button', {
                                        'with-hover': !showArrowTogler,
                                    }), onClick: () => setOpened((prev) => !prev), children: [showArrowTogler && ((0, jsx_runtime_1.jsx)(uikit_1.ArrowToggle, { direction: isOpened ? 'top' : 'bottom', className: b('arrow') })), (0, jsx_runtime_1.jsx)(uikit_1.Text, { variant: "subheader-1", color: "hint", className: b('title'), children: title })] }), (0, jsx_runtime_1.jsx)("div", { className: b('dropdown', { opened: isOpened }), children: (0, jsx_runtime_1.jsx)(uikit_1.DropdownMenu, { icon: (0, jsx_runtime_1.jsx)(uikit_1.Icon, { data: icons_1.EllipsisVertical, width: 16, height: 16 }), items: [
                                            {
                                                text: 'Clear all fields',
                                                action: () => setConfirmDialogOpen(true),
                                            },
                                        ] }) })] }), (0, jsx_runtime_1.jsx)("div", { className: b('children', { opened: isOpened }), children: (0, jsx_runtime_1.jsx)("div", { className: b('children-inner'), children: (0, jsx_runtime_1.jsx)(SectionOpenContext_1.SectionOpenContext.Provider, { value: { isOpen: isOpened ?? false, nestingLevel: nestingLevel + 1 }, children: (0, jsx_runtime_1.jsx)(Fields_1.default, { className: b('fields'), fields: fields, content: content, onUpdate: onUpdate }) }) }) })] }), (0, jsx_runtime_1.jsxs)(uikit_1.Dialog, { open: confirmDialogOpen, onClose: () => setConfirmDialogOpen(false), size: "s", children: [(0, jsx_runtime_1.jsx)(uikit_1.Dialog.Header, { caption: "Clear all fields in this block?" }), (0, jsx_runtime_1.jsx)(uikit_1.Dialog.Body, { children: (0, jsx_runtime_1.jsx)(uikit_1.Text, { variant: "body-1", children: "All field values will be deleted, and the block settings will be reset to their default state." }) }), (0, jsx_runtime_1.jsx)(uikit_1.Dialog.Footer, { textButtonApply: "Approve", textButtonCancel: "Cancel", onClickButtonApply: handleConfirmClear, onClickButtonCancel: () => setConfirmDialogOpen(false) })] })] }) }));
};
exports.default = Section;
//# sourceMappingURL=Section.js.map
