<?php

namespace GriffinForms\Admin\App\Html\Modals\ConditionalLogic;

trait Requests
{
    protected function getRequestsJs()
    {
        $this->getConditionItemTypesJs();
        $this->getConditionFieldTargetsJs();
        $this->getConditionAttributesJs();
        $this->getConditionEvaluatorsJs();
        $this->getConditionInputJs();
        $this->getSubeditorOverlayFieldsJs();
        $this->getActionItemTypesJs();
        $this->getActionFieldTargetsJs();
        $this->getActionAttributesJs();
        $this->getActionOperationsJs();
        $this->getActionInputJs();
        $this->deleteRuleEntryJs();
        $this->saveRuleJs();
        $this->deleteRuleJs();
        $this->fetchRulesJs();
        $this->getRuleJs();
    }

    protected function getConditionItemTypesJs()
    {
        $nonce = wp_create_nonce('get_condition_item_types');
        $form_id = absint(wp_unslash($_GET['form_id']));
        $loading_text = esc_html__('Loading options...', 'griffinforms-form-builder');

        echo '
        function griffinformsGetConditionItemTypes() {
            const wrapper = $("#griffinforms-logic-subeditor-items-container");
            if (!wrapper.length) {
                return;
            }

            const selectionWrapper = $("#griffinforms-logic-subeditor-item-selection-wrapper");
            const attributesWrapper = $("#griffinforms-logic-subeditor-item-attributes-wrapper");
            const evaluatorsWrapper = $("#griffinforms-logic-subeditor-attribute-evaluators-wrapper");
            const conditionWrapper = $("#griffinforms-logic-subeditor-condition-input-wrapper");

            if (selectionWrapper.length) {
                selectionWrapper.empty();
            }
            if (attributesWrapper.length) {
                attributesWrapper.empty();
            }
            if (evaluatorsWrapper.length) {
                evaluatorsWrapper.empty();
            }
            if (conditionWrapper.length) {
                conditionWrapper.empty();
            }

            const contextTypeField = $("#griffinforms-logic-context-type");
            const ruleField = $("#griffinforms-logic-context-rule");
            const entryField = $("#griffinforms-logic-context-entry");
            const groupField = $("#griffinforms-logic-context-group");

            const data = {
                action: "getConditionItemTypes",
                form_id: ' . $form_id . ',
                context_type: (contextTypeField.val() || "").toString(),
                rule_index: ruleField.val(),
                entry_index: entryField.val(),
                condition_group: (groupField.val() || "").toString(),
                nonce: "' . esc_js($nonce) . '"
            };

            griffinformsToggleSubeditor(true);
            griffinformsToggleModalSpinner();

            const placeholder = `<div class="griffinforms-logic-subeditor-label">' . esc_js($loading_text) . '</div>`;
            wrapper
                .addClass("is-loading")
                .html(placeholder);

            $.post(ajaxurl, data)
                .done(function(response) {
                    if (response && response.success && response.data && response.data.html) {
                        wrapper.removeClass("is-loading").html(response.data.html);
                        const select = wrapper.find("#griffinforms-logic-subeditor-items");
                        if (select.length) {
                            select.trigger("change");
                        }
                        griffinformsShowLogicMessage("success", response.data.msg || "Items loaded.");
                    } else if (response && response.data && response.data.msg) {
                        wrapper.removeClass("is-loading").empty();
                        griffinformsShowLogicMessage("error", response.data.msg || "Sorry, something went wrong.");
                    } else {
                        wrapper.removeClass("is-loading").empty();
                        griffinformsShowLogicMessage("error", "Sorry, something went wrong. Please try again.");
                    }
                })
                .fail(function() {
                    wrapper.removeClass("is-loading").empty();
                    griffinformsShowLogicMessage("error", "Sorry, something went wrong. Please try again.");
                })
                .always(function() {
                    griffinformsToggleSubeditor(false);
                    griffinformsToggleModalSpinner(false);
                });
        }
        ';
    }

    protected function getActionItemTypesJs()
    {
        $nonce = wp_create_nonce('get_action_item_types');
        $form_id = absint(wp_unslash($_GET['form_id']));
        $loading_text = esc_html__('Loading actions...', 'griffinforms-form-builder');

        echo '
        function griffinformsGetActionItemTypes() {
            const wrapper = $("#griffinforms-logic-subeditor-action-items-container");
            if (!wrapper.length) {
                return;
            }

            const fieldWrapper = $("#griffinforms-logic-subeditor-action-field-wrapper");
            const attributeWrapper = $("#griffinforms-logic-subeditor-action-attribute-wrapper");
            const operationWrapper = $("#griffinforms-logic-subeditor-action-operation-wrapper");
            const inputWrapper = $("#griffinforms-logic-subeditor-action-input-wrapper");

            if (fieldWrapper.length) {
                fieldWrapper.empty();
            }
            if (attributeWrapper.length) {
                attributeWrapper.empty();
            }
            if (operationWrapper.length) {
                operationWrapper.empty();
            }
            if (inputWrapper.length) {
                inputWrapper.empty();
            }

            const contextTypeField = $("#griffinforms-logic-context-type");
            const ruleField = $("#griffinforms-logic-context-rule");
            const entryField = $("#griffinforms-logic-context-entry");

            const data = {
                action: "getActionItemTypes",
                form_id: ' . $form_id . ',
                context_type: (contextTypeField.val() || "").toString(),
                rule_index: ruleField.val(),
                entry_index: entryField.val(),
                nonce: "' . esc_js($nonce) . '"
            };

            if (typeof griffinformsGetCurrentEntryPayload === "function") {
                const currentPayload = griffinformsGetCurrentEntryPayload();
                if (currentPayload && typeof currentPayload === "object" && Object.prototype.hasOwnProperty.call(currentPayload, "item") && currentPayload.item !== null) {
                    data.selected_item_value = currentPayload.item;
                }
            }

            griffinformsToggleSubeditor(true);
            griffinformsToggleModalSpinner();

            const placeholder = `<div class="griffinforms-logic-subeditor-label">' . esc_js($loading_text) . '</div>`;
            wrapper
                .addClass("is-loading")
                .html(placeholder);

            $.post(ajaxurl, data)
                .done(function(response) {
                    if (response && response.success && response.data && response.data.html) {
                        wrapper.removeClass("is-loading").html(response.data.html);
                        const select = wrapper.find("#griffinforms-logic-subeditor-action-items");
                        if (select.length) {
                            select.trigger("change");
                        }
                        griffinformsShowLogicMessage("success", response.data.msg || "Actions loaded.");
                    } else if (response && response.data && response.data.msg) {
                        wrapper.removeClass("is-loading").empty();
                        griffinformsShowLogicMessage("error", response.data.msg || "Sorry, something went wrong.");
                    } else {
                        wrapper.removeClass("is-loading").empty();
                        griffinformsShowLogicMessage("error", "Sorry, something went wrong. Please try again.");
                    }
                })
                .fail(function() {
                    wrapper.removeClass("is-loading").empty();
                    griffinformsShowLogicMessage("error", "Sorry, something went wrong. Please try again.");
                })
                .always(function() {
                    griffinformsToggleSubeditor(false);
                    griffinformsToggleModalSpinner(false);
                });
        }
        ';
    }

    protected function getActionFieldTargetsJs()
    {
        $nonce = wp_create_nonce('get_action_field_targets');
        echo '
        function griffinformsGetActionFieldTargets() {
            const itemSelect = $("#griffinforms-logic-subeditor-action-items");
            const wrapper = $("#griffinforms-logic-subeditor-action-field-wrapper");
            const attributeWrapper = $("#griffinforms-logic-subeditor-action-attribute-wrapper");
            const operationWrapper = $("#griffinforms-logic-subeditor-action-operation-wrapper");
            const inputWrapper = $("#griffinforms-logic-subeditor-action-input-wrapper");

            if (!itemSelect.length) {
                if (wrapper.length) {
                    wrapper.empty();
                }
                if (attributeWrapper.length) {
                    attributeWrapper.empty();
                }
                if (operationWrapper.length) {
                    operationWrapper.empty();
                }
                if (inputWrapper.length) {
                    inputWrapper.empty();
                }
                return;
            }

            const actionType = (itemSelect.val() || "").toString();

            if (!actionType.length) {
                if (wrapper.length) {
                    wrapper.empty();
                }
                if (attributeWrapper.length) {
                    attributeWrapper.empty();
                }
                if (operationWrapper.length) {
                    operationWrapper.empty();
                }
                if (inputWrapper.length) {
                    inputWrapper.empty();
                }
                return;
            }

            if (actionType === "form") {
                const targetValue = (function () {
                    if (typeof griffinformsGetCurrentEntryPayload === "function") {
                        const payload = griffinformsGetCurrentEntryPayload();
                        if (payload && typeof payload === "object" && Object.prototype.hasOwnProperty.call(payload, "item_id") && payload.item_id !== null) {
                            const candidate = (payload.item_id || "").toString();
                            if (candidate.length) {
                                return candidate;
                            }
                        }
                    }
                    return "this_form";
                })();

                if (wrapper.length) {
                    const infoText = "' . esc_js(__('This rule targets the current form.', 'griffinforms-form-builder')) . '";
                    const optionLabel = "' . esc_js(__('This form', 'griffinforms-form-builder')) . '";
                    wrapper.html(
                        `<div class="griffinforms-logic-subeditor-control-wrapper text-center">
                            <div class="form-text text-muted mb-2">${infoText}</div>
                            <div class="fw-semibold mb-2">${optionLabel}</div>
                            <input type="hidden" id="griffinforms-logic-subeditor-action-field" name="item_id" value="${targetValue}" data-gf-field-type="form" />
                        </div>`
                    );
                }

                if (attributeWrapper.length) {
                    attributeWrapper.empty();
                }
                if (operationWrapper.length) {
                    operationWrapper.empty();
                }
                if (inputWrapper.length) {
                    inputWrapper.empty();
                }

                if (typeof griffinformsGetActionAttributes === "function") {
                    griffinformsGetActionAttributes();
                }
                if (typeof griffinformsSetSaveButtonDisabled === "function") {
                    griffinformsSetSaveButtonDisabled(false);
                }
                const actionBlockForm = wrapper.closest(".griffinforms-logic-subeditor-block-action");
                if (actionBlockForm.length) {
                    actionBlockForm.removeClass("is-empty");
                }
                return;
            }

            const contextTypeField = $("#griffinforms-logic-context-type");
            const ruleField = $("#griffinforms-logic-context-rule");
            const entryField = $("#griffinforms-logic-context-entry");

            const data = {
                action: "getActionFieldTargets",
                form_id: ' . absint(wp_unslash($_GET['form_id'])) . ',
                context_type: (contextTypeField.val() || "").toString(),
                rule_index: ruleField.val(),
                entry_index: entryField.val(),
                item_type: actionType,
                nonce: "' . esc_js($nonce) . '"
            };

            if (typeof griffinformsGetCurrentEntryPayload === "function") {
                const currentPayload = griffinformsGetCurrentEntryPayload();
                if (currentPayload && typeof currentPayload === "object" && Object.prototype.hasOwnProperty.call(currentPayload, "item_id") && currentPayload.item_id !== null) {
                    data.selected_field_id = currentPayload.item_id;
                }
            }

            griffinformsToggleSubeditor(true);
            griffinformsToggleModalSpinner();
            if (attributeWrapper.length) {
                attributeWrapper.empty();
            }
            if (operationWrapper.length) {
                operationWrapper.empty();
            }

            $.post(ajaxurl, data)
                .done(function(response) {
                    if (response && response.success && response.data && response.data.html) {
                        wrapper.html(response.data.html);

                        const emptyNotice = wrapper.find("[data-gf-field-list-empty=\"1\"]").length > 0;
                        const actionBlock = wrapper.closest(".griffinforms-logic-subeditor-block-action");
                        if (emptyNotice) {
                            if (typeof griffinformsSetSaveButtonDisabled === "function") {
                                griffinformsSetSaveButtonDisabled(true);
                            }
                            if (attributeWrapper.length) {
                                attributeWrapper.empty();
                            }
                            if (operationWrapper.length) {
                                operationWrapper.empty();
                            }
                            if (inputWrapper.length) {
                                inputWrapper.empty();
                            }
                            if (actionBlock.length) {
                                actionBlock.addClass("is-empty");
                            }
                            return;
                        }

                        if (actionBlock.length) {
                            actionBlock.removeClass("is-empty");
                        }

                        if (typeof griffinformsSetSaveButtonDisabled === "function") {
                            griffinformsSetSaveButtonDisabled(false);
                        }

                        const control = wrapper.find("#griffinforms-logic-subeditor-action-field");
                        if (control.length) {
                            if (control.is("select")) {
                                control.trigger("change");
                            } else if (typeof griffinformsGetActionAttributes === "function") {
                                griffinformsGetActionAttributes();
                            }
                        }
                        griffinformsShowLogicMessage("success", response.data.msg || "Fields loaded.");
                    } else if (response && response.data && response.data.msg) {
                        wrapper.empty();
                        const actionBlock = wrapper.closest(".griffinforms-logic-subeditor-block-action");
                        if (actionBlock.length) {
                            actionBlock.addClass("is-empty");
                        }
                        if (typeof griffinformsSetSaveButtonDisabled === "function") {
                            griffinformsSetSaveButtonDisabled(true);
                        }
                        griffinformsShowLogicMessage("error", response.data.msg || "Sorry, something went wrong.");
                    } else {
                        wrapper.empty();
                        const actionBlock = wrapper.closest(".griffinforms-logic-subeditor-block-action");
                        if (actionBlock.length) {
                            actionBlock.addClass("is-empty");
                        }
                        if (typeof griffinformsSetSaveButtonDisabled === "function") {
                            griffinformsSetSaveButtonDisabled(true);
                        }
                        griffinformsShowLogicMessage("error", "Sorry, something went wrong. Please try again.");
                    }
                })
                .fail(function() {
                    wrapper.empty();
                    const actionBlock = wrapper.closest(".griffinforms-logic-subeditor-block-action");
                    if (actionBlock.length) {
                        actionBlock.addClass("is-empty");
                    }
                    if (typeof griffinformsSetSaveButtonDisabled === "function") {
                        griffinformsSetSaveButtonDisabled(true);
                    }
                    griffinformsShowLogicMessage("error", "Sorry, something went wrong. Please try again.");
                })
                .always(function() {
                    griffinformsToggleSubeditor(false);
                    griffinformsToggleModalSpinner(false);
                });
        }
        ';
    }

    protected function getActionAttributesJs()
    {
        $nonce = wp_create_nonce('get_action_attributes');
        echo '
        function griffinformsGetActionAttributes() {
            const fieldSelect = $("#griffinforms-logic-subeditor-action-field");
            const wrapper = $("#griffinforms-logic-subeditor-action-attribute-wrapper");
            const actionWrapper = $("#griffinforms-logic-subeditor-action-operation-wrapper");
            const inputWrapper = $("#griffinforms-logic-subeditor-action-input-wrapper");
            const selectedField = (fieldSelect.val() || "").toString();
            const itemSelect = $("#griffinforms-logic-subeditor-action-items");
            const itemType = (itemSelect.val() || "").toString();

            if (!fieldSelect.length || !selectedField.length || !itemType.length) {
                if (wrapper.length) {
                    wrapper.empty();
                }
                if (actionWrapper.length) {
                    actionWrapper.empty();
                }
                if (inputWrapper.length) {
                    inputWrapper.empty();
                }
                return;
            }

            let fieldType = "";
            let optionGroupsData = "";
            let likertRowsData = "";
            if (fieldSelect.is("select")) {
                const selectedOption = fieldSelect.find("option:selected");
                fieldType = (selectedOption.data("gf-field-type") || "").toString();
                optionGroupsData = (selectedOption.attr("data-gf-option-groups") || "").toString();
                likertRowsData = (selectedOption.attr("data-gf-likert-rows") || "").toString();
            } else {
                fieldType = (fieldSelect.data("gf-field-type") || "").toString();
                optionGroupsData = (fieldSelect.attr("data-gf-option-groups") || "").toString();
                likertRowsData = (fieldSelect.attr("data-gf-likert-rows") || "").toString();
            }

            const contextTypeField = $("#griffinforms-logic-context-type");
            const ruleField = $("#griffinforms-logic-context-rule");
            const entryField = $("#griffinforms-logic-context-entry");

            const data = {
                action: "getActionAttributes",
                form_id: ' . absint(wp_unslash($_GET['form_id'])) . ',
                field_id: selectedField,
                field_type: fieldType,
                item_type: itemType,
                context_type: (contextTypeField.val() || "").toString(),
                rule_index: ruleField.val(),
                entry_index: entryField.val(),
                nonce: "' . esc_js($nonce) . '"
            };

            if (optionGroupsData.length) {
                data.field_option_groups = optionGroupsData;
            }

            if (likertRowsData.length) {
                data.field_likert_rows = likertRowsData;
            }

            if (typeof griffinformsGetCurrentEntryPayload === "function") {
                const currentPayload = griffinformsGetCurrentEntryPayload();
                if (currentPayload && typeof currentPayload === "object" && Object.prototype.hasOwnProperty.call(currentPayload, "attribute") && currentPayload.attribute !== null) {
                    data.selected_attribute = currentPayload.attribute;
                }
            }

            griffinformsToggleSubeditor(true);
            griffinformsToggleModalSpinner();
            if (actionWrapper.length) {
                actionWrapper.empty();
            }
            if (inputWrapper.length) {
                inputWrapper.empty();
            }

            $.post(ajaxurl, data)
                .done(function(response) {
                    if (response && response.success && response.data && response.data.html) {
                        wrapper.html(response.data.html);
                        const select = wrapper.find("#griffinforms-logic-subeditor-action-attributes");
                        if (select.length) {
                            select.trigger("change");
                        }
                        griffinformsShowLogicMessage("success", response.data.msg || "Attributes loaded.");
                    } else if (response && response.data && response.data.msg) {
                        wrapper.empty();
                        griffinformsShowLogicMessage("error", response.data.msg || "Sorry, something went wrong.");
                    } else {
                        wrapper.empty();
                        griffinformsShowLogicMessage("error", "Sorry, something went wrong. Please try again.");
                    }
                })
                .fail(function() {
                    wrapper.empty();
                    griffinformsShowLogicMessage("error", "Sorry, something went wrong. Please try again.");
                })
                .always(function() {
                    griffinformsToggleSubeditor(false);
                    griffinformsToggleModalSpinner(false);
                });
        }
        ';
    }

    protected function getActionOperationsJs()
    {
        $nonce = wp_create_nonce('get_action_operations');
        echo '
        function griffinformsGetActionOperations() {
            const attributeSelect = $("#griffinforms-logic-subeditor-action-attributes");
            const wrapper = $("#griffinforms-logic-subeditor-action-operation-wrapper");
            const inputWrapper = $("#griffinforms-logic-subeditor-action-input-wrapper");
            const attribute = (attributeSelect.val() || "").toString();
            const itemSelect = $("#griffinforms-logic-subeditor-action-items");
            const itemType = (itemSelect.val() || "").toString();

            if (!attributeSelect.length || !attribute.length || !itemType.length) {
                if (wrapper.length) {
                    wrapper.empty();
                }
                if (inputWrapper.length) {
                    inputWrapper.empty();
                }
                return;
            }

            const contextTypeField = $("#griffinforms-logic-context-type");
            const ruleField = $("#griffinforms-logic-context-rule");
            const entryField = $("#griffinforms-logic-context-entry");
            const fieldSelect = $("#griffinforms-logic-subeditor-action-field");
            let fieldType = "";
            let optionGroupsData = "";
            let likertRowsData = "";
            let fieldIdValue = "";
            if (fieldSelect.length) {
                if (fieldSelect.is("select")) {
                    const selectedOption = fieldSelect.find("option:selected");
                    fieldType = (selectedOption.data("gf-field-type") || "").toString();
                    optionGroupsData = (selectedOption.attr("data-gf-option-groups") || "").toString();
                    likertRowsData = (selectedOption.attr("data-gf-likert-rows") || "").toString();
                    fieldIdValue = (selectedOption.val() || "").toString();
                } else {
                    fieldType = (fieldSelect.data("gf-field-type") || "").toString();
                    optionGroupsData = (fieldSelect.attr("data-gf-option-groups") || "").toString();
                    likertRowsData = (fieldSelect.attr("data-gf-likert-rows") || "").toString();
                    fieldIdValue = (fieldSelect.val() || "").toString();
                }
            }

            const data = {
                action: "getActionOperations",
                form_id: ' . absint(wp_unslash($_GET['form_id'])) . ',
                attribute: attribute,
                item_type: itemType,
                context_type: (contextTypeField.val() || "").toString(),
                rule_index: ruleField.val(),
                entry_index: entryField.val(),
                field_type: fieldType,
                nonce: "' . esc_js($nonce) . '"
            };

            if (optionGroupsData.length) {
                data.field_option_groups = optionGroupsData;
            }

            if (likertRowsData.length) {
                data.field_likert_rows = likertRowsData;
            }

            if (fieldIdValue.length) {
                data.field_id = fieldIdValue;
            }

            if (typeof griffinformsGetCurrentEntryPayload === "function") {
                const currentPayload = griffinformsGetCurrentEntryPayload();
                if (currentPayload && typeof currentPayload === "object" && Object.prototype.hasOwnProperty.call(currentPayload, "action") && currentPayload.action !== null) {
                    data.selected_action = currentPayload.action;
                }
            }

            griffinformsToggleSubeditor(true);
            griffinformsToggleModalSpinner();
            if (inputWrapper.length) {
                inputWrapper.empty();
            }

            $.post(ajaxurl, data)
                .done(function(response) {
                    if (response && response.success && response.data && response.data.html) {
                        wrapper.html(response.data.html);
                        const select = wrapper.find("#griffinforms-logic-subeditor-action-operation");
                        if (select.length) {
                            select.trigger("change");
                        } else if (typeof griffinformsGetActionInput === "function") {
                            griffinformsGetActionInput();
                        }
                        griffinformsShowLogicMessage("success", response.data.msg || "Actions loaded.");
                        if (typeof griffinformsGetCurrentEntryPayload === "function") {
                            const currentPayload = griffinformsGetCurrentEntryPayload();
                            if (currentPayload && typeof currentPayload === "object" && typeof griffinformsSetCurrentEntryPayload === "function") {
                                delete currentPayload.action;
                                griffinformsSetCurrentEntryPayload(currentPayload);
                            }
                        }
                    } else if (response && response.data && response.data.msg) {
                        wrapper.empty();
                        if (inputWrapper.length) {
                            inputWrapper.empty();
                        }
                        griffinformsShowLogicMessage("error", response.data.msg || "Sorry, something went wrong.");
                    } else {
                        wrapper.empty();
                        if (inputWrapper.length) {
                            inputWrapper.empty();
                        }
                        griffinformsShowLogicMessage("error", "Sorry, something went wrong. Please try again.");
                    }
                })
                .fail(function() {
                    wrapper.empty();
                    if (inputWrapper.length) {
                        inputWrapper.empty();
                    }
                    griffinformsShowLogicMessage("error", "Sorry, something went wrong. Please try again.");
                })
                .always(function() {
                    griffinformsToggleSubeditor(false);
                    griffinformsToggleModalSpinner(false);
                });
        }
        ';
    }

    protected function deleteRuleEntryJs()
    {
        $nonce = wp_create_nonce('delete_rule_entry');
        $form_id = absint(wp_unslash($_GET['form_id']));
        $generic_error = esc_html__('Sorry, something went wrong. Please try again.', 'griffinforms-form-builder');
        $default_success = esc_html__('Entry deleted successfully.', 'griffinforms-form-builder');

        echo '
        function griffinformsDeleteRuleEntry(contextType, ruleIndex, entryIndex, conditionGroup = "") {
            const normalizedContext = (typeof contextType === "string" && contextType.toLowerCase() === "action")
                ? "action"
                : "condition";
            const parsedRuleIndex = parseInt(ruleIndex, 10);
            const parsedEntryIndex = parseInt(entryIndex, 10);
            if (!Number.isFinite(parsedRuleIndex) || !Number.isFinite(parsedEntryIndex)) {
                return;
            }

            let groupValue = "";
            if (normalizedContext === "condition") {
                const rawGroup = (typeof conditionGroup === "string" ? conditionGroup : "").toLowerCase();
                groupValue = rawGroup === "any" ? "any" : "all";
            }

            const data = {
                action: "deleteRuleEntry",
                form_id: ' . $form_id . ',
                context_type: normalizedContext,
                rule_index: parsedRuleIndex,
                entry_index: parsedEntryIndex,
                condition_group: groupValue,
                nonce: "' . esc_js($nonce) . '"
            };

            let triggeredRefresh = false;

            griffinformsToggleModalSpinner(true);

            $.post(ajaxurl, data)
                .done(function(response) {
                    if (response && response.success) {
                        const message = response.data && response.data.msg
                            ? response.data.msg
                            : "' . esc_js($default_success) . '";
                        griffinformsShowLogicMessage("success", message);
                        document.dispatchEvent(new CustomEvent("form-updated", { detail: { type: "conditional_logic", formId: data.form_id } }));
                        if (typeof griffinformsGetRule === "function") {
                            triggeredRefresh = true;
                            griffinformsGetRule(parsedRuleIndex);
                        }
                    } else if (response && response.data && response.data.msg) {
                        griffinformsShowLogicMessage("error", response.data.msg);
                    } else {
                        griffinformsShowLogicMessage("error", "' . esc_js($generic_error) . '");
                    }
                })
                .fail(function() {
                    griffinformsShowLogicMessage("error", "' . esc_js($generic_error) . '");
                })
                .always(function() {
                    if (!triggeredRefresh) {
                        griffinformsToggleModalSpinner(false);
                    }
                });
        }
        ';
    }
    protected function getConditionFieldTargetsJs()
    {
        $nonce = wp_create_nonce('get_condition_field_targets');
        echo '
        function griffinformsGetConditionFieldTargets() {
            const select = $("#griffinforms-logic-subeditor-items");
            const wrapper = $("#griffinforms-logic-subeditor-item-selection-wrapper");
            const attributesWrapper = $("#griffinforms-logic-subeditor-item-attributes-wrapper");
            const evaluatorsWrapper = $("#griffinforms-logic-subeditor-attribute-evaluators-wrapper");
            const conditionWrapper = $("#griffinforms-logic-subeditor-condition-input-wrapper");
            const ifType = (select.val() || "").toString();

            if (!select.length || !ifType.length) {
                wrapper.empty();
                return;
            }

            const data = {
                action: "getConditionFieldTargets",
                item_type: ifType,
                form_id: ' . absint(wp_unslash($_GET['form_id'])) . ',
                nonce: "' . esc_js($nonce) . '"
            };

            let entryPayloadRef = null;
            if (typeof griffinformsGetCurrentEntryPayload === "function") {
                const currentPayload = griffinformsGetCurrentEntryPayload();
                if (currentPayload && typeof currentPayload === "object") {
                    entryPayloadRef = currentPayload;
                    if (Object.prototype.hasOwnProperty.call(currentPayload, "item_id") && currentPayload.item_id !== null) {
                        data.selected_item_id = currentPayload.item_id;
                    }
                    if (Object.prototype.hasOwnProperty.call(currentPayload, "item") && currentPayload.item !== null) {
                        data.selected_item_value = currentPayload.item;
                    }
                }
            }

            griffinformsToggleSubeditor(true);
            griffinformsToggleModalSpinner();

            $.post(ajaxurl, data)
                .done(function(response) {
                    if (response && response.success && response.data && response.data.html) {
                        wrapper.html(response.data.html);

                        const emptyNotice = wrapper.find("[data-gf-field-list-empty=\"1\"]").length > 0;
                        const conditionBlock = wrapper.closest(".griffinforms-logic-subeditor-block-condition");
                        if (emptyNotice) {
                            if (attributesWrapper.length) {
                                attributesWrapper.empty();
                            }
                            if (evaluatorsWrapper.length) {
                                evaluatorsWrapper.empty();
                            }
                            if (conditionWrapper.length) {
                                conditionWrapper.empty();
                            }
                            if (typeof griffinformsSetSaveButtonDisabled === "function") {
                                griffinformsSetSaveButtonDisabled(true);
                            }
                            if (conditionBlock.length) {
                                conditionBlock.addClass("is-empty");
                            }
                            return;
                        }

                        if (conditionBlock.length) {
                            conditionBlock.removeClass("is-empty");
                        }

                        if (typeof griffinformsSetSaveButtonDisabled === "function") {
                            griffinformsSetSaveButtonDisabled(false);
                        }

                        if (typeof griffinformsGetConditionAttributes === "function") {
                            griffinformsGetConditionAttributes();
                        }
                        griffinformsShowLogicMessage("success", response.data.msg || "Items loaded.");
                        if (entryPayloadRef && typeof entryPayloadRef === "object" && typeof griffinformsSetCurrentEntryPayload === "function") {
                            delete entryPayloadRef.item_id;
                            delete entryPayloadRef.item;
                            griffinformsSetCurrentEntryPayload(entryPayloadRef);
                        }
                    } else if (response && response.data && response.data.msg) {
                        wrapper.empty();
                        const conditionBlock = wrapper.closest(".griffinforms-logic-subeditor-block-condition");
                        if (conditionBlock.length) {
                            conditionBlock.addClass("is-empty");
                        }
                        if (typeof griffinformsSetSaveButtonDisabled === "function") {
                            griffinformsSetSaveButtonDisabled(true);
                        }
                        griffinformsShowLogicMessage("error", response.data.msg || "Sorry, something went wrong.");
                    } else {
                        wrapper.empty();
                        const conditionBlock = wrapper.closest(".griffinforms-logic-subeditor-block-condition");
                        if (conditionBlock.length) {
                            conditionBlock.addClass("is-empty");
                        }
                        if (typeof griffinformsSetSaveButtonDisabled === "function") {
                            griffinformsSetSaveButtonDisabled(true);
                        }
                        griffinformsShowLogicMessage("error", "Sorry, something went wrong. Please try again.");
                    }
                })
                .fail(function() {
                    wrapper.empty();
                    if (attributesWrapper.length) {
                        attributesWrapper.empty();
                    }
                    if (evaluatorsWrapper.length) {
                        evaluatorsWrapper.empty();
                    }
                    if (conditionWrapper.length) {
                        conditionWrapper.empty();
                    }
                    const conditionBlock = wrapper.closest(".griffinforms-logic-subeditor-block-condition");
                    if (conditionBlock.length) {
                        conditionBlock.addClass("is-empty");
                    }
                    if (typeof griffinformsSetSaveButtonDisabled === "function") {
                        griffinformsSetSaveButtonDisabled(true);
                    }
                    griffinformsShowLogicMessage("error", "Sorry, something went wrong. Please try again.");
                })
                .always(function() {
                    griffinformsToggleSubeditor(false);
                    griffinformsToggleModalSpinner(false);
                });
        }
        ';
    }

    protected function getConditionAttributesJs()
    {
        $nonce = wp_create_nonce('get_condition_attributes');
        echo '
        function griffinformsGetConditionAttributes() {
            const itemTypeSelect = $("#griffinforms-logic-subeditor-items");
            const itemSelect = $("#griffinforms-logic-subeditor-item-selection-wrapper").find("select");
            const wrapper = $("#griffinforms-logic-subeditor-item-attributes-wrapper");
            const itemType = (itemTypeSelect.val() || "").toString();

            const data = {
                action: "getConditionAttributes",
                item_type: itemType,
                form_id: ' . absint(wp_unslash($_GET['form_id'])) . ',
                nonce: "' . esc_js($nonce) . '"
            };

            if (itemType === "field") {
                const selectedOption = itemSelect.find("option:selected");
                data.field_id = selectedOption.val();
                data.field_type = selectedOption.data("gf-field-type");
            }

            let entryPayloadRef = null;
            if (typeof griffinformsGetCurrentEntryPayload === "function") {
                const currentPayload = griffinformsGetCurrentEntryPayload();
                if (currentPayload && typeof currentPayload === "object") {
                    entryPayloadRef = currentPayload;
                    if (Object.prototype.hasOwnProperty.call(currentPayload, "attribute") && currentPayload.attribute !== null) {
                        data.selected_attribute = currentPayload.attribute;
                    }
                }
            }

            griffinformsToggleSubeditor(true);
            griffinformsToggleModalSpinner();

            $.post(ajaxurl, data)
                .done(function(response) {
                    if (response && response.success && response.data && response.data.html) {
                        wrapper.html(response.data.html);
                        if (typeof griffinformsGetConditionEvaluators === "function") {
                            griffinformsGetConditionEvaluators();
                        }
                        griffinformsShowLogicMessage("success", response.data.msg || "Items loaded.");
                        if (entryPayloadRef && typeof entryPayloadRef === "object" && typeof griffinformsSetCurrentEntryPayload === "function") {
                            delete entryPayloadRef.attribute;
                            griffinformsSetCurrentEntryPayload(entryPayloadRef);
                        }
                    } else if (response && response.data && response.data.msg) {
                        wrapper.empty();
                        griffinformsShowLogicMessage("error", response.data.msg || "Sorry, something went wrong.");
                    } else {
                        wrapper.empty();
                        griffinformsShowLogicMessage("error", "Sorry, something went wrong. Please try again.");
                    }
                })
                .fail(function() {
                    wrapper.empty();
                    griffinformsShowLogicMessage("error", "Sorry, something went wrong. Please try again.");
                })
                .always(function() {
                    griffinformsToggleSubeditor(false);
                    griffinformsToggleModalSpinner(false);
                });
        }
        ';
    }

    protected function getConditionEvaluatorsJs()
    {
        $nonce = wp_create_nonce('get_condition_evaluators');
        echo '
        function griffinformsGetConditionEvaluators() {
            const itemTypeSelect = $("#griffinforms-logic-subeditor-items");
            const itemSelect = $("#griffinforms-logic-subeditor-item-selection-wrapper").find("select");
            const attrSelect = $("#griffinforms-logic-subeditor-attributes-wrapper").find("select");
            const wrapper = $("#griffinforms-logic-subeditor-attribute-evaluators-wrapper");
            const conditionWrapper = $("#griffinforms-logic-subeditor-condition-input-wrapper");
            const itemType = (itemTypeSelect.val() || "").toString();
            const attr = (attrSelect.val() || "").toString();

            const data = {
                action: "getConditionEvaluators",
                item_type: itemType,
                attr: attr,
                form_id: ' . absint(wp_unslash($_GET['form_id'])) . ',
                nonce: "' . esc_js($nonce) . '"
            };

            if (itemType === "field") {
                const selectedOption = itemSelect.find("option:selected");
                data.field_id = selectedOption.val();
                data.field_type = selectedOption.data("gf-field-type");
            }

            let entryPayloadRef = null;
            if (typeof griffinformsGetCurrentEntryPayload === "function") {
                const currentPayload = griffinformsGetCurrentEntryPayload();
                if (currentPayload && typeof currentPayload === "object") {
                    entryPayloadRef = currentPayload;
                    if (Object.prototype.hasOwnProperty.call(currentPayload, "evaluator") && currentPayload.evaluator !== null) {
                        data.selected_evaluator = currentPayload.evaluator;
                    }
                }
            }

            griffinformsToggleSubeditor(true);
            griffinformsToggleModalSpinner();

            $.post(ajaxurl, data)
                .done(function(response) {
                    if (response && response.success && response.data && response.data.html) {
                        wrapper.html(response.data.html);
                        griffinformsGetConditionInput();
                        griffinformsShowLogicMessage("success", response.data.msg || "Items loaded.");
                        if (entryPayloadRef && typeof entryPayloadRef === "object" && typeof griffinformsSetCurrentEntryPayload === "function") {
                            delete entryPayloadRef.evaluator;
                            griffinformsSetCurrentEntryPayload(entryPayloadRef);
                        }
                    } else if (response && response.data && response.data.msg) {
                        wrapper.empty();
                        conditionWrapper.empty();
                        griffinformsShowLogicMessage("error", response.data.msg || "Sorry, something went wrong.");
                    } else {
                        wrapper.empty();
                        conditionWrapper.empty();
                        griffinformsShowLogicMessage("error", "Sorry, something went wrong. Please try again.");
                    }
                })
                .fail(function() {
                    wrapper.empty();
                    conditionWrapper.empty();
                    griffinformsShowLogicMessage("error", "Sorry, something went wrong. Please try again.");
                })
                .always(function() {
                    griffinformsToggleSubeditor(false);
                    griffinformsToggleModalSpinner(false);
                });
        }
        ';
    }

    protected function getConditionInputJs()
    {
        $nonce = wp_create_nonce('get_condition_input');
        echo '
        function griffinformsGetConditionInput() {
            const itemTypeSelect = $("#griffinforms-logic-subeditor-items");
            const itemSelect = $("#griffinforms-logic-subeditor-item-selection-wrapper").find("select");
            const attrSelect = $("#griffinforms-logic-subeditor-attributes-wrapper").find("select");
            const conditionSelect = $("#griffinforms-logic-subeditor-attribute-evaluators-wrapper").find("select");
            const wrapper = $("#griffinforms-logic-subeditor-condition-input-wrapper");
            const itemType = (itemTypeSelect.val() || "").toString();
            const attr = (attrSelect.val() || "").toString();
            const condition = (conditionSelect.val() || "").toString();

            const data = {
                action: "getConditionInput",
                item_type: itemType,
                attr: attr,
                condition: condition,
                form_id: ' . absint(wp_unslash($_GET['form_id'])) . ',
                nonce: "' . esc_js($nonce) . '"
            };

            if (itemType === "field") {
                const selectedOption = itemSelect.find("option:selected");
                data.field_id = selectedOption.val();
                data.field_type = selectedOption.data("gf-field-type");
            }

            let entryPayloadRef = null;
            if (typeof griffinformsGetCurrentEntryPayload === "function") {
                const currentPayload = griffinformsGetCurrentEntryPayload();
                if (currentPayload && typeof currentPayload === "object") {
                    entryPayloadRef = currentPayload;
                    if (Object.prototype.hasOwnProperty.call(currentPayload, "input") && currentPayload.input !== null) {
                        data.input_value = currentPayload.input;
                    }
                }
            }

            griffinformsToggleSubeditor(true);
            griffinformsToggleModalSpinner();
            wrapper.empty();

            $.post(ajaxurl, data)
                .done(function(response) {
                    if (response && response.success && response.data) {
                        const needsInput = response.data.meta && response.data.meta.needs_input;
                        if (needsInput && response.data.html) {
                            wrapper.html(response.data.html);
                            if (typeof griffinformsInitConditionInputs === "function") {
                                griffinformsInitConditionInputs(wrapper);
                            }
                        } else {
                            wrapper.empty();
                        }
                        griffinformsShowLogicMessage("success", response.data.msg || "Input value retrieved successfully.");
                        if (entryPayloadRef && typeof entryPayloadRef === "object" && typeof griffinformsSetCurrentEntryPayload === "function") {
                            delete entryPayloadRef.input;
                            griffinformsSetCurrentEntryPayload(entryPayloadRef);
                        }
                    } else if (response && response.data && response.data.msg) {
                        wrapper.empty();
                        griffinformsShowLogicMessage("error", response.data.msg || "Sorry, something went wrong.");
                    } else {
                        wrapper.empty();
                        griffinformsShowLogicMessage("error", "Sorry, something went wrong. Please try again.");
                    }
                })
                .fail(function() {
                    wrapper.empty();
                    griffinformsShowLogicMessage("error", "Sorry, something went wrong. Please try again.");
                })
                .always(function() {
                    griffinformsToggleSubeditor(false);
                    griffinformsToggleModalSpinner(false);
                });
        }
        ';
    }

    protected function getSubeditorOverlayFieldsJs()
    {
        $nonce = wp_create_nonce('get_subeditor_overlay_fields');
        echo '
        function griffinformsOverlayFetchFields(options) {
            const overlay = $("#griffinforms-logic-subeditor-overlay");
            if (!overlay.length || typeof jQuery === "undefined" || typeof jQuery.Deferred !== "function") {
                return $.Deferred(function(defer) {
                    defer.reject();
                }).promise();
            }

            const settings = $.extend({
                forceRefresh: false,
                beforeSend: null,
                onSuccess: null,
                onError: null,
                onComplete: null
            }, options || {});

            const cacheKey = "gfOverlayFields";
            const cachedFields = overlay.data(cacheKey);
            if (!settings.forceRefresh && Array.isArray(cachedFields) && cachedFields.length) {
                if (typeof settings.onSuccess === "function") {
                    settings.onSuccess(cachedFields, { fromCache: true });
                }
                if (typeof settings.onComplete === "function") {
                    settings.onComplete();
                }
                return $.Deferred(function(defer) {
                    defer.resolve(cachedFields);
                }).promise();
            }

            const requestData = {
                action: "getSubeditorOverlayFields",
                form_id: ' . absint(wp_unslash($_GET['form_id'])) . ',
                nonce: "' . esc_js($nonce) . '"
            };

            if (typeof settings.beforeSend === "function") {
                settings.beforeSend();
            }

            let subeditorToggled = false;
            if (typeof griffinformsToggleSubeditor === "function") {
                griffinformsToggleSubeditor(true);
                subeditorToggled = true;
            }
            griffinformsToggleModalSpinner(true);

            return $.post(ajaxurl, requestData)
                .done(function(response) {
                    if (response && response.success && response.data && Array.isArray(response.data.fields)) {
                        overlay.data(cacheKey, response.data.fields);
                        if (typeof settings.onSuccess === "function") {
                            settings.onSuccess(response.data.fields, response);
                        }
                        const successMessage = (response.data && response.data.msg)
                            ? response.data.msg
                            : "' . esc_js(__('Overlay options loaded successfully.', 'griffinforms-form-builder')) . '";
                        griffinformsShowLogicMessage("success", successMessage);
                        return;
                    }

                    const errorMessage = (response && response.data && response.data.msg)
                        ? response.data.msg
                        : "' . esc_js(__('Sorry, something went wrong. Please try again.', 'griffinforms-form-builder')) . '";
                    if (typeof settings.onError === "function") {
                        settings.onError(errorMessage, response);
                    }
                    griffinformsShowLogicMessage("error", errorMessage);
                })
                .fail(function(jqXHR) {
                    const message = "' . esc_js(__('Sorry, something went wrong. Please try again.', 'griffinforms-form-builder')) . '";
                    if (typeof settings.onError === "function") {
                        settings.onError(message, null, jqXHR);
                    }
                    griffinformsShowLogicMessage("error", message);
                })
                .always(function() {
                    if (typeof settings.onComplete === "function") {
                        settings.onComplete();
                    }
                    if (subeditorToggled && typeof griffinformsToggleSubeditor === "function") {
                        griffinformsToggleSubeditor(false);
                    }
                    griffinformsToggleModalSpinner(false);
                });
        }
        ';
    }

    protected function getActionInputJs()
    {
        $nonce = wp_create_nonce('get_action_input');
        echo '
        function griffinformsGetActionInput() {
            const attributeSelect = $("#griffinforms-logic-subeditor-action-attributes");
            const operationSelect = $("#griffinforms-logic-subeditor-action-operation");
            const fieldSelect = $("#griffinforms-logic-subeditor-action-field");
            const wrapper = $("#griffinforms-logic-subeditor-action-input-wrapper");
            const itemSelect = $("#griffinforms-logic-subeditor-action-items");
            const itemType = (itemSelect.val() || "").toString();

            if (!wrapper.length) {
                return;
            }

            const attribute = (attributeSelect.val() || "").toString();
            const operation = (operationSelect.val() || "").toString();

            if (!attribute.length || !operation.length || !itemType.length) {
                wrapper.empty();
                return;
            }

            let optionGroupsData = "";
            let likertRowsData = "";
            if (fieldSelect.length) {
                if (fieldSelect.is("select")) {
                    const selectedOption = fieldSelect.find("option:selected");
                    optionGroupsData = (selectedOption.attr("data-gf-option-groups") || "").toString();
                    likertRowsData = (selectedOption.attr("data-gf-likert-rows") || "").toString();
                } else {
                    optionGroupsData = (fieldSelect.attr("data-gf-option-groups") || "").toString();
                    likertRowsData = (fieldSelect.attr("data-gf-likert-rows") || "").toString();
                }
            }

            const data = {
                action: "getActionInput",
                attribute: attribute,
                operation: operation,
                form_id: ' . absint(wp_unslash($_GET['form_id'])) . ',
                item_type: itemType,
                nonce: "' . esc_js($nonce) . '"
            };

            if (fieldSelect.length) {
                if (fieldSelect.is("select")) {
                    const selectedOption = fieldSelect.find("option:selected");
                    data.field_id = selectedOption.val();
                    data.field_type = (selectedOption.data("gf-field-type") || "").toString();
                } else {
                    data.field_id = fieldSelect.val();
                    data.field_type = (fieldSelect.data("gf-field-type") || "").toString();
                }
            }

            if (optionGroupsData.length) {
                data.field_option_groups = optionGroupsData;
            }

            if (likertRowsData.length) {
                data.field_likert_rows = likertRowsData;
            }

            let entryPayloadRef = null;
            if (typeof griffinformsGetCurrentEntryPayload === "function") {
                const currentPayload = griffinformsGetCurrentEntryPayload();
                if (currentPayload && typeof currentPayload === "object") {
                    entryPayloadRef = currentPayload;
                    if (Object.prototype.hasOwnProperty.call(currentPayload, "input") && currentPayload.input !== null) {
                        data.input_value = currentPayload.input;
                    }
                }
            }

            griffinformsToggleSubeditor(true);
            griffinformsToggleModalSpinner();
            wrapper.empty();

            $.post(ajaxurl, data)
                .done(function(response) {
                    if (response && response.success && response.data) {
                        const needsInput = response.data.meta && response.data.meta.needs_input;
                        if (needsInput && response.data.html) {
                            wrapper.html(response.data.html);
                            const actionInputType = (response.data.meta && response.data.meta.input_type) ? response.data.meta.input_type : null;
                            $(document).trigger("griffinforms:logic-action-input-rendered", { wrapper: wrapper, input_type: actionInputType });
                        } else {
                            wrapper.empty();
                            $(document).trigger("griffinforms:logic-action-input-rendered", { wrapper: wrapper, input_type: null });
                        }
                        griffinformsShowLogicMessage("success", response.data.msg || "Action input loaded.");
                        if (entryPayloadRef && typeof entryPayloadRef === "object" && typeof griffinformsSetCurrentEntryPayload === "function") {
                            delete entryPayloadRef.input;
                            griffinformsSetCurrentEntryPayload(entryPayloadRef);
                        }
                    } else if (response && response.data && response.data.msg) {
                        wrapper.empty();
                        griffinformsShowLogicMessage("error", response.data.msg || "Sorry, something went wrong.");
                    } else {
                        wrapper.empty();
                        griffinformsShowLogicMessage("error", "Sorry, something went wrong. Please try again.");
                    }
                })
                .fail(function() {
                    wrapper.empty();
                    griffinformsShowLogicMessage("error", "Sorry, something went wrong. Please try again.");
                })
                .always(function() {
                    griffinformsToggleSubeditor(false);
                    griffinformsToggleModalSpinner(false);
                });
        }
        ';
    }

    protected function saveRuleJs()
    {
        $nonce = wp_create_nonce('save_rule');
        echo '
        $(document).on("click", "#griffinforms-logic-subeditor-save", function () {
            const wrapper = $(".griffinforms-logic-subeditor-wrapper");
            if (!wrapper.length) {
                return;
            }

            if (typeof griffinformsSyncOptionGroupInput === "function") {
                griffinformsSyncOptionGroupInput(wrapper);
            }

            if (typeof griffinformsSyncLikertRowInput === "function") {
                griffinformsSyncLikertRowInput(wrapper);
            }

            const payload = {
                action: "saveRule",
                form_id: ' . absint(wp_unslash($_GET['form_id'])) . ',
                nonce: "' . esc_js($nonce) . '",
            };

            let actionOperationValue = null;

            wrapper.find("input, select, textarea").each(function () {
                const element = $(this);
                const name = (element.attr("name") || element.attr("id") || "").toString();
                if (!name) {
                    return;
                }
                if (element.is(":checkbox")) {
                    payload[name] = element.is(":checked") ? "1" : "0";
                } else if (element.is(":radio")) {
                    if (element.is(":checked")) {
                        payload[name] = element.val();
                    }
                } else if (name === "action") {
                    actionOperationValue = element.val();
                } else if ((element.data("gfInputType") || "").toString() === "date") {
                    const format = (element.data("gfDateFormat") || "yy-mm-dd").toString();
                    const timestamp = (typeof griffinformsDateValueToTimestamp === "function")
                        ? griffinformsDateValueToTimestamp(element.val(), format)
                        : null;
                    if (timestamp !== null) {
                        payload[name] = timestamp;
                    } else {
                        payload[name] = element.val();
                    }
                } else {
                    payload[name] = element.val();
                }
            });

            payload["context_type"] = (wrapper.data("gf-context-type") || "").toString();
            const ctxRuleIdx = parseInt(wrapper.data("gf-rule-index"), 10);
            payload["context_rule_index"] = Number.isFinite(ctxRuleIdx) ? ctxRuleIdx : "";
            const ctxEntryIdx = parseInt(wrapper.data("gf-entry-index"), 10);
            payload["context_entry_index"] = Number.isFinite(ctxEntryIdx) ? ctxEntryIdx : "";
            const ctxGroupRaw = (wrapper.data("gf-condition-group") || $("#griffinforms-logic-context-group").val() || "").toString();
            const ctxGroupValue = ctxGroupRaw.length ? ctxGroupRaw.toLowerCase() : "";
            payload["condition_group"] = ctxGroupValue;

            if (actionOperationValue !== null) {
                payload.operation = actionOperationValue;
            }

            const itemTypeForValidation = (payload.item || "").toString().toLowerCase();
            if (itemTypeForValidation === "field") {
                const selectedFieldId = (payload.item_id || "").toString();
                if (!selectedFieldId.length) {
                    griffinformsShowLogicMessage("error", ' . wp_json_encode(__('Select a field before saving this rule entry.', 'griffinforms-form-builder')) . ');
                    return;
                }
            }

            const requiredInputs = wrapper.find(".griffinforms-condition-input, .griffinforms-action-input")
                .filter(function () {
                    const field = $(this);
                    return !field.is(":disabled") && field.is(":visible");
                });

            if (requiredInputs.length) {
                const hasValue = requiredInputs.toArray().some(function (node) {
                    const field = $(node);
                    if (field.attr("data-gf-rich-input") === "1") {
                        const $hidden = field.siblings(".gf-logic-rich-input-hidden");
                        const hiddenVal = $hidden.length ? ($hidden.val() || "").toString().trim() : "";
                        return hiddenVal.length > 0;
                    }
                    const rawValue = field.val();
                    const value = Array.isArray(rawValue)
                        ? rawValue.join(" ").trim()
                        : (rawValue ?? "").toString().trim();
                    return value.length > 0;
                });

                if (!hasValue) {
                    griffinformsShowLogicMessage("error", ' . wp_json_encode(__('Please provide a value before saving this rule entry.', 'griffinforms-form-builder')) . ');
                    return;
                }
            }

            const activeAttribute = (payload.attribute || "").toString();
            if (activeAttribute === "option_groups") {
                let rawGroups = (payload.input || "").toString().trim();
                let parsedGroups = [];
                if (rawGroups.length) {
                    try {
                        const decoded = JSON.parse(rawGroups);
                        if (Array.isArray(decoded)) {
                            parsedGroups = decoded;
                        }
                    } catch (err) {
                        parsedGroups = rawGroups.split(/[\n,]+/);
                    }
                }

                const hasSelection = Array.isArray(parsedGroups) && parsedGroups.some(function (entry) {
                    if (entry === null || typeof entry === "undefined") {
                        return false;
                    }
                    const label = Array.isArray(entry) ? entry.join(" ").trim() : String(entry).trim();
                    return label.length > 0;
                });

                if (!hasSelection) {
                    griffinformsShowLogicMessage("error", ' . wp_json_encode(__('Select at least one option group before saving this rule entry.', 'griffinforms-form-builder')) . ');
                    return;
                }
            }

            if (activeAttribute === "rows") {
                let rawRows = (payload.input || "").toString().trim();
                let parsedRows = [];
                if (rawRows.length) {
                    try {
                        const decoded = JSON.parse(rawRows);
                        if (Array.isArray(decoded)) {
                            parsedRows = decoded;
                        }
                    } catch (err) {}
                }

                const hasRowSelection = parsedRows.some(function (entry) {
                    return entry !== null && typeof entry !== "undefined" && String(entry).trim().length > 0;
                });

                if (!hasRowSelection) {
                    griffinformsShowLogicMessage("error", ' . wp_json_encode(__('Select at least one row before saving this rule entry.', 'griffinforms-form-builder')) . ');
                    return;
                }
            }

            griffinformsToggleSubeditor(true);
            griffinformsToggleModalSpinner();

            $.post(ajaxurl, payload)
                .done(function(response) {
                    if (response && response.success) {
                        const msg = response.data && response.data.msg ? response.data.msg : "";
                        griffinformsShowLogicMessage("success", msg || "Rule saved successfully.");
                        document.dispatchEvent(new CustomEvent("form-updated", { detail: { type: "conditional_logic", formId: payload.form_id } }));
                        // Trigger custom event after successful save
                        $(document).trigger("griffinforms:rule-saved", { response: response });
                        if (response.data) {
                            const parsedRuleIndex = parseInt(response.data.rule_index, 10);
                            const parsedEntryIndex = parseInt(response.data.entry_index, 10);
                            const hasRuleIndex = Number.isFinite(parsedRuleIndex);
                            const hasEntryIndex = Number.isFinite(parsedEntryIndex);
                            if (hasRuleIndex) {
                                wrapper.attr("data-gf-rule-index", parsedRuleIndex);
                                wrapper.data("gf-rule-index", parsedRuleIndex);
                                $("#griffinforms-logic-context-rule").val(parsedRuleIndex);
                                editorWrapper.attr("data-gf-active-rule", parsedRuleIndex);
                                window.griffinformsActiveRuleIndex = parsedRuleIndex;
                                if (typeof griffinformsGetRule === "function") {
                                    griffinformsGetRule(parsedRuleIndex);
                                }
                            }
                            if (hasEntryIndex) {
                                wrapper.attr("data-gf-entry-index", parsedEntryIndex);
                                wrapper.data("gf-entry-index", parsedEntryIndex);
                                $("#griffinforms-logic-context-entry").val(parsedEntryIndex);
                            }
                            const contextType = (response.data.context || "").toString();
                            if (contextType.length) {
                                wrapper.attr("data-gf-context-type", contextType);
                                wrapper.data("gf-context-type", contextType);
                                $("#griffinforms-logic-context-type").val(contextType);
                            }
                            if (contextType === "condition") {
                                const responseGroup = (response.data.condition_group || ctxGroupValue || "").toString();
                                wrapper.attr("data-gf-condition-group", responseGroup);
                                wrapper.data("gf-condition-group", responseGroup);
                                $("#griffinforms-logic-context-group").val(responseGroup);
                            }
                        }
                    } else if (response && response.data && response.data.msg) {
                        griffinformsShowLogicMessage("error", response.data.msg);
                    } else {
                        griffinformsShowLogicMessage("error", "Sorry, something went wrong. Please try again.");
                    }
                })
                .fail(function(jqXHR) {
                    if (window.console && typeof window.console.error === "function") {
                        console.error("griffinformsSaveRule failed:", jqXHR && jqXHR.responseText ? jqXHR.responseText : jqXHR);
                    }
                    const errorText = (jqXHR && jqXHR.responseJSON && jqXHR.responseJSON.data && jqXHR.responseJSON.data.msg)
                        ? jqXHR.responseJSON.data.msg
                        : "Sorry, something went wrong. Please try again.";
                    griffinformsShowLogicMessage("error", errorText);
                })
                .always(function() {
                    griffinformsToggleSubeditor(false);
                    griffinformsToggleModalSpinner(false);
                });
        });
        ';
    }

    protected function deleteRuleJs()
    {
        $nonce = wp_create_nonce('delete_rule');
        $form_id = absint(wp_unslash($_GET['form_id']));
        $success_text = esc_html__('Rule deleted successfully.', 'griffinforms-form-builder');
        $generic_error = esc_html__('Sorry, something went wrong. Please try again.', 'griffinforms-form-builder');

        echo '
        function griffinformsDeleteRule(ruleIndex) {
            const parsedIndex = parseInt(ruleIndex, 10);
            if (!Number.isFinite(parsedIndex)) {
                return;
            }

            const data = {
                action: "deleteRule",
                form_id: ' . $form_id . ',
                rule_index: parsedIndex,
                nonce: "' . esc_js($nonce) . '"
            };

            let triggeredRefresh = false;

            griffinformsToggleModalSpinner(true);

            $.post(ajaxurl, data)
                .done(function(response) {
                    if (response && response.success) {
                        const message = response.data && response.data.msg ? response.data.msg : "' . esc_js($success_text) . '";
                        griffinformsShowLogicMessage("success", message);
                        document.dispatchEvent(new CustomEvent("form-updated", { detail: { type: "conditional_logic", formId: data.form_id } }));
                        // Trigger custom event after successful delete
                        $(document).trigger("griffinforms:rule-deleted", { response: response });
                        if (typeof showRulesList === "function") {
                            triggeredRefresh = true;
                            showRulesList(true);
                        } else if (typeof griffinformsFetchRules === "function") {
                            triggeredRefresh = true;
                            griffinformsFetchRules();
                        }
                    } else if (response && response.data && response.data.msg) {
                        griffinformsShowLogicMessage("error", response.data.msg);
                    } else {
                        griffinformsShowLogicMessage("error", "' . esc_js($generic_error) . '");
                    }
                })
                .fail(function() {
                    griffinformsShowLogicMessage("error", "' . esc_js($generic_error) . '");
                })
                .always(function() {
                    if (!triggeredRefresh) {
                        griffinformsToggleModalSpinner(false);
                    }
                });
        }
        ';
    }

    protected function fetchRulesJs()
    {
        $nonce = wp_create_nonce('fetch_rules');
        echo '
        function griffinformsFetchRules() {
            const wrapper = $(".griffinforms-logic-list-wrapper");
            const placeholderClass = "griffinforms-logic-rule-placeholder";
            const addRuleSlab = wrapper.find(".griffinforms-add-rule-slab");
            const placeholderCount = 3;
            let placeholdersHtml = "";
            for (let idx = 0; idx < placeholderCount; idx += 1) {
                placeholdersHtml += `
                    <div class="${placeholderClass} mb-3">
                        <div class="placeholder-glow">
                            <span class="placeholder col-8 placeholder-lg d-block mb-2"></span>
                            <span class="placeholder col-6 d-block mb-1"></span>
                            <span class="placeholder col-5 d-block"></span>
                        </div>
                    </div>`;
            }

            wrapper.find("." + placeholderClass).remove();
            wrapper.addClass("is-loading");
            if (addRuleSlab.length) {
                addRuleSlab.before(placeholdersHtml);
            } else {
                wrapper.append(placeholdersHtml);
            }

            const data = {
                action: "fetchRules",
                form_id: ' . absint(wp_unslash($_GET['form_id'])) . ',
                nonce: "' . esc_js($nonce) . '"
            };

            griffinformsToggleModalSpinner(true);

            $.post(ajaxurl, data)
                .done(function(response) {
                    wrapper.removeClass("is-loading");
                    wrapper.find("." + placeholderClass).remove();
                    if (response && response.success && response.data && response.data.html) {
                        const addRuleSlab = wrapper.find(".griffinforms-add-rule-slab");
                        const newHtml = response.data.html;
                        wrapper.find(".griffinforms-logic-rules-loading").remove();
                        if (addRuleSlab.length) {
                            wrapper.find(".griffinforms-logic-rule-item, .griffinforms-logic-rules-empty, .griffinforms-logic-rules-empty-wrapper").remove();
                            addRuleSlab.before(newHtml);
                        } else {
                            wrapper.html(newHtml);
                        }
                        griffinformsShowLogicMessage("success", response.data.msg || "Rules loaded.");
                    } else if (response && response.data && response.data.msg) {
                        griffinformsShowLogicMessage("info", response.data.msg);
                    } else {
                        griffinformsShowLogicMessage("info", "No rules found.");
                    }
                })
                .fail(function() {
                    wrapper.removeClass("is-loading");
                    wrapper.find("." + placeholderClass).remove();
                    griffinformsShowLogicMessage("error", "Sorry, we could not load rules. Please try again.");
                })
                .always(function() {
                    wrapper.removeClass("is-loading");
                    wrapper.find("." + placeholderClass).remove();
                    griffinformsToggleModalSpinner(false);
                });
        }
        ';
    }

    protected function getRuleJs()
    {
        $nonce = wp_create_nonce('get_rule');
        $form_id = absint(wp_unslash($_GET['form_id']));
        echo '
        if (typeof window.griffinformsActiveRuleIndex === "undefined") {
            window.griffinformsActiveRuleIndex = null;
        }

        function griffinformsResetRuleEditor() {
            const conditionGroups = $(".griffinforms-logic-editor-conditions-wrapper .griffinforms-condition-group-condition");
            conditionGroups.each(function () {
                const group = $(this);
                group.find(".griffinforms-logic-condition-item, .griffinforms-logic-empty, .griffinforms-logic-entry-placeholder").remove();
            });

            const actionGroup = $(".griffinforms-logic-editor-actions-wrapper .griffinforms-condition-group-action");
            actionGroup.find(".griffinforms-logic-action-item, .griffinforms-logic-empty, .griffinforms-logic-entry-placeholder").remove();

            if (typeof griffinformsSetRuleTitle === "function") {
                griffinformsSetRuleTitle("");
            }

            const subeditor = $(".griffinforms-logic-subeditor-wrapper");
            if (subeditor.length) {
                subeditor.attr("data-gf-condition-group", "");
                subeditor.data("gf-condition-group", "");
            }
            const groupField = $("#griffinforms-logic-context-group");
            if (groupField.length) {
                groupField.val("");
            }
        }

        function griffinformsInjectRuleEditorHtml(payload) {
            if (!payload || !payload.html) {
                return;
            }

            const allGroup = $(".griffinforms-condition-group-condition[data-gf-group=\"all\"]");
            const anyGroup = $(".griffinforms-condition-group-condition[data-gf-group=\"any\"]");
            const actionGroup = $(".griffinforms-condition-group-action[data-gf-group=\"actions\"]");

            $(".griffinforms-logic-entry-placeholder").remove();

            const allSlab = allGroup.find(".griffinforms-add-condition-slab[data-gf-group=\"all\"]");
            const anySlab = anyGroup.find(".griffinforms-add-condition-slab[data-gf-group=\"any\"]");
            const actionSlab = actionGroup.find(".griffinforms-add-action-slab[data-gf-group=\"actions\"]");

            if (payload.html.conditions && typeof payload.html.conditions.all === "string") {
                allGroup.find(".griffinforms-logic-condition-item, .griffinforms-logic-empty").remove();
                if (allSlab.length) {
                    allSlab.before(payload.html.conditions.all);
                } else {
                    allGroup.prepend(payload.html.conditions.all);
                }
            }

            if (payload.html.conditions && typeof payload.html.conditions.any === "string") {
                anyGroup.find(".griffinforms-logic-condition-item, .griffinforms-logic-empty").remove();
                if (anySlab.length) {
                    anySlab.before(payload.html.conditions.any);
                } else {
                    anyGroup.prepend(payload.html.conditions.any);
                }
            }

            if (typeof payload.html.actions === "string") {
                actionGroup.find(".griffinforms-logic-action-item, .griffinforms-logic-empty").remove();
                if (actionSlab.length) {
                    actionSlab.before(payload.html.actions);
                } else {
                    actionGroup.prepend(payload.html.actions);
                }
            }

            if (typeof window.griffinformsHighlightItem === "function") {
                const subeditor = $(".griffinforms-logic-subeditor-wrapper");
                const activeType = (subeditor.data("gf-context-type") || "").toString();
                const activeRule = parseInt(subeditor.data("gf-rule-index"), 10);
                const activeEntry = parseInt(subeditor.data("gf-entry-index"), 10);
                const activeGroup = (subeditor.data("gf-condition-group") || "").toString();
                window.griffinformsHighlightItem(activeType, activeRule, activeEntry, activeGroup);
            }

            if (typeof griffinformsApplyConnectorDelays === "function") {
                griffinformsApplyConnectorDelays();
            }
        }

        const ENTRY_PLACEHOLDER_HTML = `
            <div class="griffinforms-logic-entry-placeholder mb-2">
                <div class="placeholder-glow">
                    <span class="placeholder col-9 d-block mb-2"></span>
                    <span class="placeholder col-5 d-block"></span>
                </div>
            </div>`;

        function griffinformsInsertEntryPlaceholders(groupSelector, slabSelector) {
            const group = $(groupSelector);
            if (!group.length) {
                return;
            }

            const slab = slabSelector ? group.find(slabSelector) : $([]);
            group.find(".griffinforms-logic-condition-item, .griffinforms-logic-action-item, .griffinforms-logic-empty").remove();
            group.find(".griffinforms-logic-entry-placeholder").remove();

            for (let idx = 0; idx < 2; idx += 1) {
                if (slab.length) {
                    slab.before(ENTRY_PLACEHOLDER_HTML);
                } else {
                    group.prepend(ENTRY_PLACEHOLDER_HTML);
                }
            }
        }

        function griffinformsGetRule(ruleIndex) {
            const normalizedIndex = parseInt(ruleIndex, 10);
            let resolvedIndex = Number.isFinite(normalizedIndex) ? normalizedIndex : parseInt(editorWrapper.attr("data-gf-active-rule"), 10);

            if (!Number.isFinite(resolvedIndex) && Number.isFinite(window.griffinformsActiveRuleIndex)) {
                resolvedIndex = parseInt(window.griffinformsActiveRuleIndex, 10);
            }

            if (!Number.isFinite(resolvedIndex)) {
                griffinformsResetRuleEditor();
                return;
            }

            window.griffinformsActiveRuleIndex = resolvedIndex;
            editorWrapper.attr("data-gf-active-rule", resolvedIndex);

            const data = {
                action: "getRule",
                form_id: ' . $form_id . ',
                rule_index: resolvedIndex,
                nonce: "' . esc_js($nonce) . '"
            };

            if (typeof griffinformsPauseConnectorAnimation === "function") {
                griffinformsPauseConnectorAnimation();
            }

            griffinformsInsertEntryPlaceholders(
                ".griffinforms-condition-group-condition[data-gf-group=\"all\"]",
                ".griffinforms-add-condition-slab[data-gf-group=\"all\"]"
            );
            griffinformsInsertEntryPlaceholders(
                ".griffinforms-condition-group-condition[data-gf-group=\"any\"]",
                ".griffinforms-add-condition-slab[data-gf-group=\"any\"]"
            );
            griffinformsInsertEntryPlaceholders(
                ".griffinforms-condition-group-action[data-gf-group=\"actions\"]",
                ".griffinforms-add-action-slab[data-gf-group=\"actions\"]"
            );

            griffinformsToggleModalSpinner(true);

            $.post(ajaxurl, data)
                .done(function(response) {
                    if (response && response.success && response.data) {
                        let activeRuleIndex = parseInt(response.data.rule_index, 10);
                        if (!Number.isFinite(activeRuleIndex)) {
                            activeRuleIndex = resolvedIndex;
                        }
                        if (Number.isFinite(activeRuleIndex)) {
                            window.griffinformsActiveRuleIndex = activeRuleIndex;
                            editorWrapper.attr("data-gf-active-rule", activeRuleIndex);
                        }
                        if (typeof griffinformsSetRuleTitle === "function") {
                            const ruleTitle = response.data.label || "";
                            griffinformsSetRuleTitle(ruleTitle);
                        }
                        griffinformsInjectRuleEditorHtml(response.data);
                        if (typeof griffinformsResumeConnectorAnimation === "function") {
                            griffinformsResumeConnectorAnimation();
                        }
                        griffinformsShowLogicMessage("success", response.data.msg || "Rule loaded.");
                    } else if (response && response.data && response.data.msg) {
                        $(".griffinforms-logic-entry-placeholder").remove();
                        if (typeof griffinformsSetRuleTitle === "function") {
                            griffinformsSetRuleTitle("");
                        }
                        griffinformsShowLogicMessage("error", response.data.msg);
                    } else {
                        $(".griffinforms-logic-entry-placeholder").remove();
                        if (typeof griffinformsSetRuleTitle === "function") {
                            griffinformsSetRuleTitle("");
                        }
                        griffinformsShowLogicMessage("error", "Sorry, we could not load this rule. Please try again.");
                    }
                })
                .fail(function() {
                    $(".griffinforms-logic-entry-placeholder").remove();
                    if (typeof griffinformsSetRuleTitle === "function") {
                        griffinformsSetRuleTitle("");
                    }
                    griffinformsShowLogicMessage("error", "Sorry, we could not load this rule. Please try again.");
                })
                .always(function() {
                    griffinformsToggleModalSpinner(false);
                });
        }
        ';
    }

}
