import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import * as React from 'react';
import { EllipsisVertical, Plus, TrashBin } from '@gravity-ui/icons';
import { ArrowToggle, Button, Card, Dialog, DropdownMenu, Icon, Text } from '@gravity-ui/uikit';
import { formGeneratorCn } from "../../utils/cn.js";
import { clearSectionFormContent, findAllNames, findNameWithIndexName, getArrayPathForNameWithIndexName, getSpliceTarget, getValueByPath, sectionHasContentData, } from "../../utils/fields.js";
import Base from "../Base/Base.js";
import Fields from "../Fields/Fields.js";
import { SectionOpenContext } from "./SectionOpenContext.js";
import './Section.css';
const b = 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);
    const nestingLevel = parentContext?.nestingLevel ?? 0;
    // --- Static section state ---
    const [isOpened, setOpened] = React.useState(opened);
    const [confirmDialogOpen, setConfirmDialogOpen] = React.useState(false);
    const hasData = 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) {
            clearSectionFormContent(fields, onUpdate);
        }
        setConfirmDialogOpen(false);
        setOpened(false);
    };
    // --- Group mode state ---
    const [rowKeys, setRowKeys] = React.useState([]);
    const nameWithIndexName = React.useMemo(() => (isGroupMode && index ? findNameWithIndexName(fields, index) : undefined), [fields, index, isGroupMode]);
    const arrayPath = React.useMemo(() => nameWithIndexName && index
        ? getArrayPathForNameWithIndexName(nameWithIndexName, index)
        : undefined, [nameWithIndexName, index]);
    const valuesInside = React.useMemo(() => (arrayPath ? 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 = findAllNames(replaceIndex(itemIndex));
        const resolvedName = names.find((name) => {
            const splice = getSpliceTarget(nameWithIndexName, name, index);
            return splice !== undefined && splice.itemIndex === itemIndex;
        }) ?? names[0];
        if (!resolvedName) {
            return;
        }
        const spliceTarget = 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 = (_jsxs("div", { className: b('card-header'), children: [cardTitle && (_jsx(Text, { variant: "subheader-2", className: b('card-title'), children: cardTitle })), _jsx(Button, { view: "flat", onClick: deleteItem(rowIndex), children: _jsx(Icon, { width: 16, height: 16, data: TrashBin }) })] }));
            const inner = (_jsx(SectionOpenContext.Provider, { value: { isOpen: true, nestingLevel: nestingLevel + 1 }, children: _jsx(Fields, { fields: replaceIndex(rowIndex), content: content, onUpdate: onUpdate }) }));
            if (itemView === 'clear') {
                return (_jsxs("div", { className: b('item-clear'), children: [header, inner] }, rowKey));
            }
            return (_jsxs(Card, { className: b('card'), children: [header, inner] }, rowKey));
        };
        return (_jsx(Base, { when: when, content: content, children: _jsxs("div", { className: b({ nested: nestingLevel > 0 }, className), children: [hasGroupLabel && (_jsx("div", { className: b('header'), children: _jsxs("button", { type: "button", className: b('header-button', { 'with-hover': isEmpty }), onClick: isEmpty ? handleAdd : () => setOpened((prev) => !prev), children: [!isEmpty && (_jsx(ArrowToggle, { direction: isGroupOpen ? 'top' : 'bottom', className: b('arrow') })), _jsx(Text, { variant: "subheader-1", color: "hint", className: b('title'), children: title }), isEmpty && _jsx(Plus, { width: 16, height: 16, className: b('plus') })] }) })), _jsx("div", { className: b('children', {
                            opened: !isEmpty && (!hasGroupLabel || isGroupOpen),
                        }), children: _jsxs("div", { className: b('children-inner'), children: [rowKeys.map((rowKey, rowIndex) => renderItem(rowKey, rowIndex)), withAddButton && !isEmpty && (_jsxs(Button, { onClick: handleAdd, children: ["Add ", addButtonLabel] }))] }) })] }) }));
    }
    // --- Static section render ---
    return (_jsx(Base, { when: when, content: content, children: _jsxs(React.Fragment, { children: [_jsxs("div", { className: b({ opened: isOpened, nested: nestingLevel > 0 }, className), children: [_jsxs("div", { className: b('header'), children: [_jsxs("button", { type: "button", className: b('header-button', {
                                        'with-hover': !showArrowTogler,
                                    }), onClick: () => setOpened((prev) => !prev), children: [showArrowTogler && (_jsx(ArrowToggle, { direction: isOpened ? 'top' : 'bottom', className: b('arrow') })), _jsx(Text, { variant: "subheader-1", color: "hint", className: b('title'), children: title })] }), _jsx("div", { className: b('dropdown', { opened: isOpened }), children: _jsx(DropdownMenu, { icon: _jsx(Icon, { data: EllipsisVertical, width: 16, height: 16 }), items: [
                                            {
                                                text: 'Clear all fields',
                                                action: () => setConfirmDialogOpen(true),
                                            },
                                        ] }) })] }), _jsx("div", { className: b('children', { opened: isOpened }), children: _jsx("div", { className: b('children-inner'), children: _jsx(SectionOpenContext.Provider, { value: { isOpen: isOpened ?? false, nestingLevel: nestingLevel + 1 }, children: _jsx(Fields, { className: b('fields'), fields: fields, content: content, onUpdate: onUpdate }) }) }) })] }), _jsxs(Dialog, { open: confirmDialogOpen, onClose: () => setConfirmDialogOpen(false), size: "s", children: [_jsx(Dialog.Header, { caption: "Clear all fields in this block?" }), _jsx(Dialog.Body, { children: _jsx(Text, { variant: "body-1", children: "All field values will be deleted, and the block settings will be reset to their default state." }) }), _jsx(Dialog.Footer, { textButtonApply: "Approve", textButtonCancel: "Cancel", onClickButtonApply: handleConfirmClear, onClickButtonCancel: () => setConfirmDialogOpen(false) })] })] }) }));
};
export default Section;
//# sourceMappingURL=Section.js.map
