import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
// (C) 2022-2026 GoodData Corporation
import { useMemo, useState } from "react";
import cx from "classnames";
import { useIntl } from "react-intl";
import { IntlWrapper } from "@gooddata/sdk-ui";
import { Button } from "../../Button/Button.js";
import { Typography } from "../../Typography/Typography.js";
import { useId } from "../../utils/useId.js";
import { Dialog } from "../Dialog.js";
import { BubbleHeaderSeparator } from "./BubbleHeaderSeparator.js";
import { StylingEditorDialogFooter, } from "./StylingEditorDialogFooter.js";
import { StylingExample } from "./StylingExample.js";
/**
 * @internal
 */
export function StylingEditorDialog(props) {
    return (_jsx(IntlWrapper, { locale: props.locale, children: _jsx(StylingEditorDialogCore, { ...props }) }));
}
function StylingEditorDialogCore({ title, tooltip, link, stylingItem, examples, exampleToColorPreview, onClose, onSubmit, onCancel, disableSubmit, showProgressIndicator, showBackButton, onHelpClick, onExit = () => { }, className, onInvalidDefinition = () => { }, validateDefinition, }) {
    const intl = useIntl();
    const providedExamples = !!examples && examples.length !== 0 && !!exampleToColorPreview;
    const initialNameField = stylingItem?.name ?? "";
    const initialDefinitionField = stylingItem?.content ? JSON.stringify(stylingItem?.content, null, 4) : "";
    const [nameField, setNameField] = useState(initialNameField);
    const [definitionField, setDefinitionField] = useState(initialDefinitionField);
    const fieldsChanged = useMemo(() => {
        try {
            const parsedDefinition = JSON.parse(definitionField);
            const formattedDefinition = JSON.stringify(parsedDefinition, null, 4);
            return nameField !== initialNameField || formattedDefinition !== initialDefinitionField;
        }
        catch {
            // initial state of the fields is presumed to be valid,
            // so if JSON throws error, definition was changed
            return true;
        }
    }, [nameField, initialNameField, definitionField, initialDefinitionField]);
    const validName = useMemo(() => nameField !== "", [nameField]);
    const validDefinition = useMemo(() => {
        try {
            JSON.parse(definitionField);
            return true;
        }
        catch {
            return false;
        }
    }, [definitionField]);
    // Content-level validation (e.g. theme color values) runs only on well-formed JSON.
    const definitionContentError = useMemo(() => {
        if (!validateDefinition || !validDefinition) {
            return undefined;
        }
        try {
            return validateDefinition(JSON.parse(definitionField));
        }
        catch (error) {
            // a buggy validator must not crash the dialog; degrade gracefully and let the user proceed
            console.error("StylingEditorDialog: the provided validateDefinition callback threw.", error);
            return undefined;
        }
    }, [validateDefinition, validDefinition, definitionField]);
    const validFields = useMemo(() => validName && validDefinition && !definitionContentError, [validName, validDefinition, definitionContentError]);
    const isSubmitDisabled = useMemo(() => !validFields || !fieldsChanged || disableSubmit, [validFields, fieldsChanged, disableSubmit]);
    const emptyDefinition = useMemo(() => definitionField === "", [definitionField]);
    const errorMessage = useMemo(() => {
        if (!validName) {
            return intl.formatMessage({ id: "stylingEditor.dialog.name.required" });
        }
        if (emptyDefinition) {
            return intl.formatMessage({ id: "stylingEditor.dialog.definition.required" });
        }
        if (!validDefinition) {
            if (stylingItem?.ref) {
                onInvalidDefinition?.(stylingItem.ref);
            }
            return intl.formatMessage({ id: "stylingEditor.dialog.definition.invalid" });
        }
        if (definitionContentError) {
            return definitionContentError;
        }
        return undefined;
    }, [
        validName,
        emptyDefinition,
        validDefinition,
        definitionContentError,
        onInvalidDefinition,
        stylingItem?.ref,
        intl,
    ]);
    const getFinalStylingItem = (original, definition, name) => {
        return {
            ...(original || {}),
            content: JSON.parse(definition),
            name,
        };
    };
    const titleElementId = useId();
    return (_jsxs(Dialog, { className: cx("gd-styling-editor-dialog", {
            "gd-styling-editor-dialog-create": providedExamples,
        }, className), onClose: () => {
            onExit?.(nameField, definitionField);
            onClose?.();
        }, displayCloseButton: true, submitOnEnterKey: false, accessibilityConfig: { titleElementId }, children: [
            _jsxs("div", { className: "gd-styling-editor-dialog-header", children: [showBackButton ? (_jsx("div", { className: "gd-styling-editor-dialog-header-back-button", children: _jsx(Button, { className: "gd-button-primary gd-button-icon-only gd-icon-navigateleft s-navigate-back-button", onClick: () => {
                                onExit?.(nameField, definitionField);
                                onClose?.();
                            } }) })) : null, _jsx(Typography, { tagName: "h2", className: "gd-styling-editor-dialog-header-title", id: titleElementId, children: title })
                ] }), _jsxs("div", { className: "gd-styling-editor-dialog-content", children: [
                    _jsxs("form", { className: "gd-styling-editor-dialog-content-form", onSubmit: (e) => e.preventDefault(), children: [
                            _jsxs("label", { className: "gd-styling-editor-dialog-content-form-input", children: [intl.formatMessage({ id: "stylingEditor.dialog.name" }), _jsx("input", { "aria-label": "Styling item name", className: "gd-input-field s-input-field", type: "text", value: nameField, onChange: (e) => setNameField(e.target.value) })
                                ] }), _jsxs("label", { className: "gd-styling-editor-dialog-content-form-textarea", children: [intl.formatMessage({ id: "stylingEditor.dialog.definition" }), _jsx("textarea", { "aria-label": "Styling item definition", className: "gd-input-field s-textarea-field", wrap: "off", value: definitionField, onChange: (e) => setDefinitionField(e.target.value) })
                                ] })
                        ] }), providedExamples ? (_jsxs("div", { className: cx("gd-styling-editor-dialog-content-examples", "s-gd-styling-editor-dialog-content-examples"), children: [
                            _jsx(BubbleHeaderSeparator, { title: intl.formatMessage({ id: "stylingEditor.dialog.examples" }), message: tooltip }), _jsx("div", { className: "gd-styling-editor-dialog-content-examples-list", children: examples.map((example, index) => (_jsx(StylingExample, { name: example.name ?? "", colors: exampleToColorPreview(example.content), onClick: () => {
                                        setNameField(example.name ?? "");
                                        setDefinitionField(JSON.stringify(example.content, null, 4));
                                    } }, index))) })
                        ] })) : null] }), _jsx(StylingEditorDialogFooter, { disableSubmit: isSubmitDisabled, showProgressIndicator: showProgressIndicator, link: link, errorMessage: errorMessage, onSubmit: () => onSubmit?.(getFinalStylingItem(stylingItem, definitionField, nameField)), onCancel: () => {
                    onExit?.(nameField, definitionField);
                    onCancel?.();
                }, onHelpClick: onHelpClick })
        ] }));
}
