<?php

namespace GriffinForms\Admin\Html\FormControls\Form;

class SubmissionEdit extends \GriffinForms\Admin\Html\FormControls\Form\Format
{
    protected $form_id = 0;
    protected $upsell_registry;

    protected function setFormid()
    {
        if (isset($this->data['form_id'])) {
            $this->form_id = absint($this->data['form_id']);
        }
    }

    protected function setUpsellRegistry()
    {
        $this->upsell_registry = \GriffinForms\Includes\Upsells\UpsellRegistry::getInstance();
    }

    public function html()
    {
        $policy = $this->normalizePolicy();
        $toggle = !empty($policy['toggle']);
        $render_locked_shell = $this->upsell_registry->shouldRenderLockedShell('submission_editing');

        echo '<div class="row gf-upsell-surface' . ($render_locked_shell ? ' gf-upsell-surface-is-locked' : '') . '">';
        if ($render_locked_shell) {
            echo '<fieldset class="gf-upsell-surface__fieldset" disabled aria-disabled="true">';
        }
        echo '<div class="col-md-12 mb-3" id="griffinforms-togglesubmissionedit-wrap">';
        $this->toggleSubmissionEdit($toggle);
        echo '</div>';

        $settings_style = $toggle ? '' : ' style="display:none;"';
        echo '<div class="griffinforms-hidden-option col-md-12 mb-3" id="griffinforms-submissionedit-settings-wrap"' . $settings_style . '>';
        echo '<div class="gf-notice gf-notice-info small mb-3">';
        echo esc_html__('These rules apply only when the submission edit page is opened from a valid edit URL.', 'griffinforms-form-builder');
        echo '</div>';

        echo '<div class="row g-3">';
        echo '<div class="col-md-12" id="griffinforms-submissionedit-originalsubmitters-wrap">';
        $this->originalSubmittersToggle($policy);
        echo '</div>';

        echo '<div class="col-md-12" id="griffinforms-submissionedit-emailowners-wrap">';
        $this->emailOwnersToggle($policy);
        echo '</div>';

        echo '<div class="col-md-12 griffinforms-hidden-option" id="griffinforms-submissionedit-emailfields-wrap"' . (!empty($policy['email_owners']) ? '' : ' style="display:none;"') . '>';
        $this->emailFieldSelector($policy);
        echo '</div>';

        echo '<div class="col-md-12" id="griffinforms-submissionedit-roleaccess-wrap">';
        $this->roleAccessToggle($policy);
        echo '</div>';

        echo '<div class="col-md-12 griffinforms-hidden-option" id="griffinforms-submissionedit-roles-wrap"' . (!empty($policy['role_access']) ? '' : ' style="display:none;"') . '>';
        $this->roleSelector($policy);
        echo '</div>';

        echo '<div class="col-md-12" id="griffinforms-submissionedit-useraccess-wrap">';
        $this->userAccessToggle($policy);
        echo '</div>';

        echo '<div class="col-md-12 griffinforms-hidden-option" id="griffinforms-submissionedit-users-wrap"' . (!empty($policy['user_access']) ? '' : ' style="display:none;"') . '>';
        $this->userPicker($policy);
        echo '</div>';

        echo '<div class="col-md-12" id="griffinforms-submissionedit-maxedits-wrap">';
        $this->maxEditsInput($policy);
        echo '</div>';

        echo '<div class="col-md-12" id="griffinforms-submissionedit-time-wrap">';
        $this->timeSettings($policy);
        echo '</div>';
        echo '</div>';
        echo '</div>';
        if ($render_locked_shell) {
            echo '</fieldset>';
            echo '<div class="gf-upsell-surface__overlay">';
            $this->upsell_registry->render('submission_editing', 'overlay');
            echo '</div>';
        }
        echo '</div>';
    }

    protected function normalizePolicy(): array
    {
        $defaults = array(
            'toggle' => false,
            'original_submitters' => false,
            'email_owners' => false,
            'role_access' => false,
            'user_access' => false,
            'email_fields' => array(),
            'roles' => array(),
            'users' => array(),
            'max_edits' => 0,
            'time' => array(
                'mode' => 'none',
                'start_ts' => 0,
                'end_ts' => 0,
                'duration_days' => 0,
                'duration_hours' => 0,
                'pre_message' => '',
                'post_message' => '',
            ),
        );

        if (!is_array($this->value)) {
            return $defaults;
        }

        return array_merge($defaults, $this->value);
    }

    protected function toggleSubmissionEdit(bool $value)
    {
        $data = $this->getControlData(array('label' => __('Enable submission editing', 'griffinforms-form-builder')));
        $field = new \GriffinForms\Admin\Html\FormControls\ToggleCheckBox('toggle_submission_edit', $value ? 1 : 0, $data);
        $field->html();
        echo '<div class="form-text small text-secondary">';
        echo esc_html__('Turn this on to allow frontend edit URLs for submissions on this form.', 'griffinforms-form-builder');
        echo '</div>';
    }

    protected function originalSubmittersToggle(array $policy)
    {
        $data = $this->getControlData(array('label' => __('Original submitters', 'griffinforms-form-builder')));
        $field = new \GriffinForms\Admin\Html\FormControls\ToggleCheckBox('submission_edit_original_submitters', !empty($policy['original_submitters']) ? 1 : 0, $data);
        $field->html();
        echo '<div class="form-text small text-secondary">';
        echo esc_html__('Allow the logged-in user account that submitted the form to edit it later.', 'griffinforms-form-builder');
        echo '</div>';
    }

    protected function emailOwnersToggle(array $policy)
    {
        $data = $this->getControlData(array('label' => __('Email owners', 'griffinforms-form-builder')));
        $field = new \GriffinForms\Admin\Html\FormControls\ToggleCheckBox('submission_edit_email_owners', !empty($policy['email_owners']) ? 1 : 0, $data);
        $field->html();
        echo '<div class="form-text small text-secondary">';
        echo esc_html__('Allow users who log in with a matching email address to edit the submission.', 'griffinforms-form-builder');
        echo '</div>';
    }

    protected function roleAccessToggle(array $policy)
    {
        $data = $this->getControlData(array('label' => __('Specific roles', 'griffinforms-form-builder')));
        $field = new \GriffinForms\Admin\Html\FormControls\ToggleCheckBox('submission_edit_role_access', !empty($policy['role_access']) ? 1 : 0, $data);
        $field->html();
        echo '<div class="form-text small text-secondary">';
        echo esc_html__('Restrict editing to users who have one of the selected WordPress roles.', 'griffinforms-form-builder');
        echo '</div>';
    }

    protected function userAccessToggle(array $policy)
    {
        $data = $this->getControlData(array('label' => __('Specific users', 'griffinforms-form-builder')));
        $field = new \GriffinForms\Admin\Html\FormControls\ToggleCheckBox('submission_edit_user_access', !empty($policy['user_access']) ? 1 : 0, $data);
        $field->html();
        echo '<div class="form-text small text-secondary">';
        echo esc_html__('Restrict editing to the selected user accounts.', 'griffinforms-form-builder');
        echo '</div>';
    }

    protected function emailFieldSelector(array $policy)
    {
        $field_options = $this->getEmailFieldOptions();
        echo '<div class="border rounded p-3 bg-white">';
        echo '<div class="fw-semibold mb-1">' . esc_html__('Email fields used to identify owners', 'griffinforms-form-builder') . '</div>';
        echo '<div class="form-text small text-secondary mb-2">' . esc_html__('Select one or more email fields from this form. If a field stores multiple values, any matching email may unlock editing.', 'griffinforms-form-builder') . '</div>';

        if (empty($field_options)) {
            echo '<div class="text-secondary small">' . esc_html__('No email fields are available on this form yet.', 'griffinforms-form-builder') . '</div>';
            echo '</div>';
            return;
        }

        $field = new \GriffinForms\Admin\Html\FormControls\MultiSelect('submission_edit_email_fields', $policy['email_fields'] ?? array(), $this->getControlData());
        $field->selectOptions($field_options);
        $field->html();
        echo '</div>';
    }

    protected function roleSelector(array $policy)
    {
        $options = (array) $this->choices->getUserRoles();
        echo '<div class="border rounded p-3 bg-white">';
        echo '<div class="fw-semibold mb-1">' . esc_html__('Allowed roles', 'griffinforms-form-builder') . '</div>';
        echo '<div class="form-text small text-secondary mb-2">' . esc_html__('Choose one or more roles that may edit the submission.', 'griffinforms-form-builder') . '</div>';
        $field = new \GriffinForms\Admin\Html\FormControls\MultiSelect('submission_edit_roles', $policy['roles'] ?? array(), $this->getControlData());
        $field->selectOptions($options);
        $field->html();
        echo '</div>';
    }

    protected function userPicker(array $policy)
    {
        $selected_ids = isset($policy['users']) && is_array($policy['users']) ? array_values(array_filter(array_map('absint', $policy['users']))) : array();
        $users = !empty($selected_ids) ? get_users(array(
            'include' => $selected_ids,
            'orderby' => 'include',
            'number' => count($selected_ids),
        )) : array();
        $user_map = array();
        foreach ($users as $user) {
            if (!($user instanceof \WP_User)) {
                continue;
            }
            $user_map[$user->ID] = array(
                'display_name' => $user->display_name !== '' ? $user->display_name : $user->user_login,
                'user_email' => $user->user_email,
            );
        }

        echo '<div class="border rounded p-3 bg-white">';
        echo '<div class="fw-semibold mb-1">' . esc_html__('Specific users', 'griffinforms-form-builder') . '</div>';
        echo '<div class="form-text small text-secondary mb-2">' . esc_html__('Search registered users, then add them as pills below.', 'griffinforms-form-builder') . '</div>';
        echo '<div class="d-flex flex-wrap gap-2 align-items-center mb-2">';
        echo '<input type="search" class="form-control flex-grow-1" id="griffinforms-submissionedituser-search" placeholder="' . esc_attr__('Search users by name or email', 'griffinforms-form-builder') . '">';
        echo '<button type="button" class="button" id="griffinforms-submissionedituser-search-button">' . esc_html__('Search', 'griffinforms-form-builder') . '</button>';
        echo '</div>';
        echo '<div class="list-group mb-3" id="griffinforms-submissionedituser-results" style="display:none;"></div>';
        echo '<div class="d-flex flex-wrap gap-2" id="griffinforms-submissionedituser-pills">';
        foreach ($selected_ids as $user_id) {
            $user_id = absint($user_id);
            if ($user_id <= 0) {
                continue;
            }
            $name = isset($user_map[$user_id]['display_name']) ? $user_map[$user_id]['display_name'] : sprintf(__('User %d', 'griffinforms-form-builder'), $user_id);
            $email = isset($user_map[$user_id]['user_email']) ? $user_map[$user_id]['user_email'] : '';
            echo $this->renderUserPill($user_id, $name, $email);
        }
        echo '</div>';
        echo '<input type="hidden" id="griffinforms-submissioneditusers-hidden" value="' . esc_attr(implode(',', $selected_ids)) . '">';
        echo '</div>';
    }

    protected function maxEditsInput(array $policy)
    {
        $value = isset($policy['max_edits']) ? absint($policy['max_edits']) : 0;
        $field = new \GriffinForms\Admin\Html\FormControls\InputNumber('submission_edit_max_edits', $value, $this->getControlData());
        $field->setAttr('min', 0);
        $field_id = $field->elementId();
        echo '<label for="' . esc_attr($field_id) . '" class="form-label me-2">' . esc_html__('Maximum edit count', 'griffinforms-form-builder') . '</label>';
        $field->html();
        echo '<div class="form-text small text-secondary">';
        echo esc_html__('Set to 0 or leave blank for unlimited edits.', 'griffinforms-form-builder');
        echo '</div>';
    }

    protected function timeSettings(array $policy)
    {
        $time = isset($policy['time']) && is_array($policy['time']) ? $policy['time'] : array();
        $mode = isset($time['mode']) ? sanitize_key((string) $time['mode']) : 'none';
        if (!in_array($mode, array('none', 'window', 'duration'), true)) {
            $mode = 'none';
        }

        echo '<div class="border rounded p-3 bg-white">';
        echo '<div class="fw-semibold mb-1">' . esc_html($this->lang->getText('submission_edit_time_label')) . '</div>';
        echo '<div class="form-text small text-secondary mb-3">' . esc_html($this->lang->getText('submission_edit_time_description')) . '</div>';

        echo '<div class="mb-3" id="griffinforms-submissionedit-time-mode-wrap">';
        $field = new \GriffinForms\Admin\Html\FormControls\SelectField('submission_edit_time_mode', $mode, $this->getControlData());
        $field_id = $field->elementId();
        $field->selectOptions(array(
            'none' => $this->lang->getText('submission_edit_time_none_label'),
            'window' => $this->lang->getText('submission_edit_time_window_label'),
            'duration' => $this->lang->getText('submission_edit_time_duration_label'),
        ));
        echo '<label class="form-label me-2" for="' . esc_attr($field_id) . '">' . esc_html($this->lang->getText('submission_edit_time_mode_label')) . '</label>';
        $field->html();
        echo '<div class="form-text small text-secondary">' . esc_html($this->lang->getText('submission_edit_time_description_hint')) . '</div>';
        echo '</div>';

        echo '<div class="griffinforms-hidden-option" id="griffinforms-submissionedit-time-window-wrap"' . ($mode === 'window' ? '' : ' style="display:none;"') . '>';
        $this->timeWindowFields($time);
        echo '</div>';

        echo '<div class="griffinforms-hidden-option" id="griffinforms-submissionedit-time-duration-wrap"' . ($mode === 'duration' ? '' : ' style="display:none;"') . '>';
        $this->timeDurationFields($time);
        echo '</div>';
        echo '</div>';
    }

    protected function timeWindowFields(array $time)
    {
        $start_ts = isset($time['start_ts']) ? absint($time['start_ts']) : 0;
        $end_ts = isset($time['end_ts']) ? absint($time['end_ts']) : 0;
        $start_date = $start_ts > 0 ? wp_date('m/d/Y', $start_ts) : '';
        $start_time = $start_ts > 0 ? wp_date('H:i', $start_ts) : '';
        $end_date = $end_ts > 0 ? wp_date('m/d/Y', $end_ts) : '';
        $end_time = $end_ts > 0 ? wp_date('H:i', $end_ts) : '';
        $pre_message = isset($time['pre_message']) ? (string) $time['pre_message'] : '';
        $post_message = isset($time['post_message']) ? (string) $time['post_message'] : '';

        echo '<div class="row g-3">';
        echo '<div class="col-md-12">';
        echo '<div class="fw-semibold mb-1 me-2">' . esc_html($this->lang->getText('submission_edit_time_start_label')) . '</div>';
        echo '<div class="d-flex flex-wrap gap-2">';
        $date_field = new \GriffinForms\Admin\Html\FormControls\InputDate('submission_edit_time_window_start_date', $start_date, $this->getControlData());
        $time_field = new \GriffinForms\Admin\Html\FormControls\InputTime('submission_edit_time_window_start_time', $start_time, $this->getControlData());
        $date_field->html();
        $time_field->html();
        echo '</div>';
        echo '</div>';

        echo '<div class="col-md-12">';
        echo '<div class="fw-semibold mb-1 me-2">' . esc_html($this->lang->getText('submission_edit_time_end_label')) . '</div>';
        echo '<div class="d-flex flex-wrap gap-2">';
        $date_field = new \GriffinForms\Admin\Html\FormControls\InputDate('submission_edit_time_window_end_date', $end_date, $this->getControlData());
        $time_field = new \GriffinForms\Admin\Html\FormControls\InputTime('submission_edit_time_window_end_time', $end_time, $this->getControlData());
        $date_field->html();
        $time_field->html();
        echo '</div>';
        echo '</div>';

        echo '<div class="col-md-12">';
        echo '<div class="fw-semibold mb-1 me-2">' . esc_html($this->lang->getText('submission_edit_time_pre_message_label')) . '</div>';
        $field = new \GriffinForms\Admin\Html\FormControls\TextArea('submission_edit_time_window_pre_message', $pre_message, $this->getControlData());
        $field->html();
        echo '</div>';

        echo '<div class="col-md-12">';
        echo '<div class="fw-semibold mb-1 me-2">' . esc_html($this->lang->getText('submission_edit_time_post_message_label')) . '</div>';
        $field = new \GriffinForms\Admin\Html\FormControls\TextArea('submission_edit_time_window_post_message', $post_message, $this->getControlData());
        $field->html();
        echo '</div>';
        echo '</div>';
    }

    protected function timeDurationFields(array $time)
    {
        $duration_days = isset($time['duration_days']) ? absint($time['duration_days']) : 0;
        $duration_hours = isset($time['duration_hours']) ? absint($time['duration_hours']) : 0;
        $post_message = isset($time['post_message']) ? (string) $time['post_message'] : '';

        echo '<div class="row g-3">';
        echo '<div class="col-md-6">';
        echo '<label class="form-label me-2" for="griffinforms-submission_edit_time_duration_days-inputnumber">' . esc_html($this->lang->getText('submission_edit_time_duration_days_label')) . '</label>';
        $days = new \GriffinForms\Admin\Html\FormControls\InputNumber('submission_edit_time_duration_days', $duration_days, $this->getControlData());
        $days->setAttr('min', 0);
        $days->html();
        echo '</div>';

        echo '<div class="col-md-6">';
        echo '<label class="form-label me-2" for="griffinforms-submission_edit_time_duration_hours-inputnumber">' . esc_html($this->lang->getText('submission_edit_time_duration_hours_label')) . '</label>';
        $hours = new \GriffinForms\Admin\Html\FormControls\InputNumber('submission_edit_time_duration_hours', $duration_hours, $this->getControlData());
        $hours->setAttr('min', 0);
        $hours->html();
        echo '</div>';

        echo '<div class="col-md-12">';
        echo '<div class="fw-semibold mb-1 me-2">' . esc_html($this->lang->getText('submission_edit_time_post_message_label')) . '</div>';
        $field = new \GriffinForms\Admin\Html\FormControls\TextArea('submission_edit_time_duration_post_message', $post_message, $this->getControlData());
        $field->html();
        echo '</div>';
        echo '</div>';
    }

    protected function getEmailFieldOptions(): array
    {
        if ($this->form_id <= 0 || !$this->sql) {
            return array();
        }

        $fields = $this->sql->fieldsInForm($this->form_id);
        $options = array();
        foreach ((array) $fields as $field) {
            if (!is_object($field)) {
                continue;
            }

            $field_type = sanitize_key((string) ($field->field_type ?? ''));
            if ($field_type !== 'inputemail') {
                continue;
            }

            $field_id = absint($field->id ?? 0);
            if ($field_id <= 0) {
                continue;
            }

            $label = trim((string) ($field->name ?? ''));
            if ($label === '') {
                $label = sprintf(__('Email field #%d', 'griffinforms-form-builder'), $field_id);
            }

            $options[$field_id] = $label;
        }

        return $options;
    }

    protected function renderUserPill(int $user_id, string $name, string $email): string
    {
        $html = '<span class="badge rounded-pill text-bg-dark d-inline-flex align-items-center gap-2 gx-user-pill" data-gf-user-id="' . esc_attr($user_id) . '" data-gf-user-name="' . esc_attr($name) . '" data-gf-user-email="' . esc_attr($email) . '">';
        $html .= '<span>' . esc_html($name) . '</span>';
        if ($email !== '') {
            $html .= '<span class="small opacity-75">' . esc_html($email) . '</span>';
        }
        $html .= '<button type="button" class="btn-close btn-close-white gx-user-pill-remove" aria-label="' . esc_attr__('Remove user', 'griffinforms-form-builder') . '"></button>';
        $html .= '</span>';
        return $html;
    }

    protected function fieldJs()
    {
        $nonce = wp_create_nonce('griffinforms_search_submission_edit_users');
        $ajax_action = 'griffinforms_search_submission_edit_users';

        ob_start();
        ?>
        jQuery(function($) {
            const ajaxAction = <?php echo wp_json_encode($ajax_action); ?>;
            const ajaxNonce = <?php echo wp_json_encode($nonce); ?>;
            const ajaxUrl = window.ajaxurl || <?php echo wp_json_encode(admin_url('admin-ajax.php')); ?>;

            function syncVisibility() {
                const $toggle         = $("#griffinforms-togglesubmissionedit-togglecheckbox");
                const $settings       = $("#griffinforms-submissionedit-settings-wrap");
                const $emailOwners    = $("#griffinforms-submissioneditemailowners-togglecheckbox");
                const $roleAccess     = $("#griffinforms-submissioneditroleaccess-togglecheckbox");
                const $userAccess     = $("#griffinforms-submissionedituseraccess-togglecheckbox");
                const $emailSettings  = $("#griffinforms-submissionedit-emailfields-wrap");
                const $roleSettings   = $("#griffinforms-submissionedit-roles-wrap");
                const $userSettings   = $("#griffinforms-submissionedit-users-wrap");
                const $timeMode       = $("#griffinforms-submissionedittimemode-selectfield");
                const $timeWindowWrap = $("#griffinforms-submissionedit-time-window-wrap");
                const $timeDurationWrap = $("#griffinforms-submissionedit-time-duration-wrap");
                const enabled  = $toggle.is(":checked");
                const timeMode = $timeMode.val() || "none";
                $settings.toggle(enabled);
                $emailSettings.toggle(enabled && $emailOwners.is(":checked"));
                $roleSettings.toggle(enabled && $roleAccess.is(":checked"));
                $userSettings.toggle(enabled && $userAccess.is(":checked"));
                $timeWindowWrap.toggle(enabled && timeMode === "window");
                $timeDurationWrap.toggle(enabled && timeMode === "duration");
            }

            function refreshHiddenUsers() {
                const $pills      = $("#griffinforms-submissionedituser-pills");
                const $hiddenUsers = $("#griffinforms-submissioneditusers-hidden");
                const ids = [];
                $pills.find("[data-gf-user-id]").each(function() {
                    const id = parseInt($(this).attr("data-gf-user-id"), 10);
                    if (id > 0) {
                        ids.push(id);
                    }
                });
                $hiddenUsers.val(ids.join(","));
            }

            function buildPill(user) {
                const email = user.user_email || "";
                const label = user.display_name || ("User " + user.id);
                const $pill = $("<span>", {
                    class: "badge rounded-pill text-bg-dark d-inline-flex align-items-center gap-2 gx-user-pill",
                    "data-gf-user-id": user.id,
                    "data-gf-user-name": label,
                    "data-gf-user-email": email
                });
                $pill.append($("<span>").text(label));
                if (email) {
                    $pill.append($("<span>", { class: "small opacity-75" }).text(email));
                }
                $pill.append($("<button>", {
                    type: "button",
                    class: "btn-close btn-close-white gx-user-pill-remove",
                    "aria-label": "Remove user"
                }));
                return $pill;
            }

            function addUser(user) {
                const $pills = $("#griffinforms-submissionedituser-pills");
                if (!user || !user.id) {
                    return;
                }
                const existing = $pills.find('[data-gf-user-id="' + user.id + '"]');
                if (existing.length) {
                    return;
                }
                $pills.append(buildPill(user));
                refreshHiddenUsers();
            }

            function renderResults(users) {
                const $results = $("#griffinforms-submissionedituser-results");
                $results.empty();
                if (!users || !users.length) {
                    $results.hide();
                    return;
                }

                users.forEach(function(user) {
                    const label = user.display_name || ("User " + user.id);
                    const email = user.user_email || "";
                    const $button = $("<button>", {
                        type: "button",
                        class: "list-group-item list-group-item-action d-flex justify-content-between align-items-center"
                    });
                    const $main = $("<span>").text(label);
                    const $secondary = $("<small>", { class: "text-secondary" }).text(email);
                    $button.append($main).append($secondary);
                    $button.data("user", user);
                    $results.append($button);
                });

                $results.show();
            }

            function searchUsers() {
                const $searchInput = $("#griffinforms-submissionedituser-search");
                const $results     = $("#griffinforms-submissionedituser-results");
                const query = $.trim($searchInput.val() || "");
                if (query.length < 2) {
                    $results.empty().hide();
                    return;
                }

                $.ajax({
                    url: ajaxUrl,
                    method: "POST",
                    dataType: "json",
                    data: {
                        action: ajaxAction,
                        nonce: ajaxNonce,
                        query: query
                    }
                }).done(function(response) {
                    if (!response || !response.success) {
                        const message = response && response.data && response.data.message
                            ? response.data.message
                            : "<?php echo esc_js(__('Unable to search users right now.', 'griffinforms-form-builder')); ?>";
                        $("#griffinforms-submissionedituser-results").empty().hide();
                        if (typeof showItemError === "function") {
                            showItemError(message, "griffinforms-submissionedituser-search");
                        }
                        return;
                    }

                    renderResults(response.data && response.data.users ? response.data.users : []);
                }).fail(function(jqXHR) {
                    $("#griffinforms-submissionedituser-results").empty().hide();
                    const message = jqXHR && jqXHR.responseJSON && jqXHR.responseJSON.data && jqXHR.responseJSON.data.message
                        ? jqXHR.responseJSON.data.message
                        : "<?php echo esc_js(__('Unable to search users right now.', 'griffinforms-form-builder')); ?>";
                    if (typeof showItemError === "function") {
                        showItemError(message, "griffinforms-submissionedituser-search");
                    }
                });
            }

            $(document).on("change", "#griffinforms-togglesubmissionedit-togglecheckbox", syncVisibility);
            $(document).on("change", "#griffinforms-submissioneditemailowners-togglecheckbox", syncVisibility);
            $(document).on("change", "#griffinforms-submissioneditroleaccess-togglecheckbox", syncVisibility);
            $(document).on("change", "#griffinforms-submissionedituseraccess-togglecheckbox", syncVisibility);
            $(document).on("change", "#griffinforms-submissionedittimemode-selectfield", syncVisibility);

            $(document).on("click", "#griffinforms-submissionedituser-results button", function() {
                const user = $(this).data("user");
                addUser(user);
                $("#griffinforms-submissionedituser-search").val("");
                $("#griffinforms-submissionedituser-results").empty().hide();
            });

            $(document).on("click", "#griffinforms-submissionedituser-pills .gx-user-pill-remove", function() {
                $(this).closest("[data-gf-user-id]").remove();
                refreshHiddenUsers();
            });

            let searchTimer = null;
            $(document).on("input", "#griffinforms-submissionedituser-search", function() {
                window.clearTimeout(searchTimer);
                searchTimer = window.setTimeout(searchUsers, 250);
            });
            $(document).on("click", "#griffinforms-submissionedituser-search-button", function(e) {
                e.preventDefault();
                searchUsers();
            });

            syncVisibility();
            refreshHiddenUsers();
        });
        <?php
        $js = ob_get_clean();
        wp_add_inline_script('griffinforms-global-js', $js);
    }
}
