(function ($) {
    "use strict";

    /* ===================================
        SweetAlert2
    ====================================== */

    if (typeof Swal !== 'undefined') {
        const GigneoAlert = Swal.mixin({});

        GigneoAlert.toast = (options = {}) => GigneoAlert.fire({
            toast: true,
            position: 'bottom-end',
            customClass: { popup: 'gigneo-sweetalert2-toast' },
            showConfirmButton: false,
            timer: 5000,
            timerProgressBar: true,
            topLayer: true,
            showCloseButton: true,
            icon: 'error',
            title: GigneoBackendCommon?.error || 'Error',
            text: GigneoBackendCommon?.went_wrong || 'Something went wrong!',
            ...options
        });

        GigneoAlert.confirm = (options = {}) => {
            const defaultClasses = {
                popup: 'gn-sweetalert2',
                confirmButton: 'gn-btn',
                cancelButton: 'gn-btn',
            };

            const userClasses = options.customClass || {};
            const icon = options.icon || 'warning';

            const mergedClasses = {
                popup: [defaultClasses.popup, userClasses.popup].filter(Boolean).join(' '),
                confirmButton: userClasses.confirmButton
                    ? [defaultClasses.confirmButton, userClasses.confirmButton].filter(Boolean).join(' ')
                    : [defaultClasses.confirmButton, icon === 'error' ? 'gn-btn-danger' : (icon === 'success' ? 'gn-btn-primary' : `gn-btn-${icon}`)].filter(Boolean).join(' '),
                cancelButton: [defaultClasses.cancelButton, userClasses.cancelButton].filter(Boolean).join(' '),
            };

            const {
                customClass: _ignoredCustomClass,
                ...restOptions
            } = options;

            return Swal.fire({
                toast: false,
                position: 'center',
                icon: options.icon || 'warning',
                title: options.title || GigneoBackendCommon?.confirmation_title || 'Are you sure?',
                text: options.text || GigneoBackendCommon?.confirmation_desc || 'Please confirm.',
                showCancelButton: true,
                confirmButtonText: options.confirmButtonText || GigneoBackendCommon?.yes || 'Yes',
                cancelButtonText: options.cancelButtonText || GigneoBackendCommon?.close || 'Close',
                showLoaderOnConfirm: options.showLoaderOnConfirm || false,
                customClass: mergedClasses,
                ...restOptions
            });
        };

        window.GigneoAlert = GigneoAlert;
    }

    /* ===================================
          Required Fields
    ====================================== */

    window.GigneoRequiredFormFields = {
        init: function (selector = $(this), proceed = true, notice = true) {
            selector.find('input,select,textarea').each(function () {
                let _input = $(this);
                let _input_type = _input.attr('type');
                let value = _input.val();

                if (_input.hasClass('gn-required-field')) {
                    if (_input_type === 'radio' || _input_type === 'checkbox') {
                        let radioGroupName = _input.attr('name');
                        if ($('input[name="' + radioGroupName + '"]:checked').length === 0) {
                            $('input[name="' + radioGroupName + '"]').addClass('gn-input-error');
                            proceed = false;
                        }
                    } else if (value === '') {
                        _input.addClass('gn-input-error');
                        proceed = false;
                    }
                }
            });

            if (!proceed && notice) {
                GigneoAlert.toast({
                    icon: 'error',
                    title: GigneoBackendCommon.error,
                    text: GigneoBackendCommon.required_fields
                });
            }

            return proceed;
        }
    };

    /* ===================================
     Plupload
   ====================================== */

    window.GigneoPlupload = {
        init: function (config) {
            let {
                browseButtonId,
                containerId,
                dropElementId,
                attachmentListId,
                allowedExtensions = ['jpg', 'jpeg', 'png', 'pdf', 'docx'],
                maxFiles = 3,
                maxSizeMb = 1,
                errorMessages = {
                    maxFiles: `Maximum ${maxFiles} files allowed.`,
                    invalidExtension: 'Invalid file extension.',
                    maxSize: `File size exceeds ${maxSizeMb}MB.`,
                    error: GigneoCommon?.error || 'Error'
                }
            } = config || {};

            let filesToUpload = [];
            let attachmentList = $(`#${attachmentListId}`);

            if (typeof plupload !== 'object') {
                return { files: [], uploader: null };
            }

            // Validate DOM elements
            if ($(`#${browseButtonId}`).length === 0 || $(`#${containerId}`).length === 0 || $(`#${dropElementId}`).length === 0 || attachmentList.length === 0) {
                return { files: [], uploader: null };
            }

            // Initialize Plupload
            let pluploadArgs = {
                browse_button: browseButtonId,
                container: containerId,
                drop_element: dropElementId,
                filters: {
                    mime_types: [{ title: 'file', extensions: allowedExtensions.join(',') }],
                    max_file_size: maxSizeMb + 'mb'
                }
            };

            let uploader = new plupload.Uploader(pluploadArgs);
            uploader.init();

            // Handle FilesAdded event
            uploader.bind('FilesAdded', function (up, files) {
                if ((filesToUpload.length + files.length) > maxFiles) {
                    GigneoAlert?.toast({
                        icon: 'error',
                        title: errorMessages.error,
                        text: errorMessages.maxFiles
                    });
                    files.forEach(f => up.removeFile(f));
                    return;
                }

                for (let i = 0; i < files.length; i++) {
                    let file = files[i];
                    let ext = file.name.includes('.') ? file.name.split('.').pop().toLowerCase() : '';

                    if (ext && !allowedExtensions.includes(ext)) {
                        GigneoAlert?.toast({
                            icon: 'error',
                            title: errorMessages.error,
                            text: errorMessages.invalidExtension
                        });
                        up.removeFile(file);
                        continue;
                    }

                    if (file.size > maxSizeMb * 1024 * 1024) {
                        GigneoAlert?.toast({
                            icon: 'error',
                            title: errorMessages.error,
                            text: errorMessages.maxSize
                        });
                        up.removeFile(file);
                        continue;
                    }

                    filesToUpload.push(file);
                    attachmentList.append(
                        `<div id="${file.id}" class="gn-attachment-item" role="listitem">${file.name}` +
                        `<button type="button" class="gn-attachment-remove" data-file-id="${file.id}" aria-label="Remove ${file.name}">` +
                        `<i class="hi hi-trash" aria-hidden="true"></i></button></div>`
                    );
                }

                up.refresh();
            });

            // Handle Plupload errors
            uploader.bind('Error', function (up, err) {
                GigneoAlert?.toast({
                    icon: 'error',
                    title: errorMessages.error,
                    text: err.message || 'An error occurred during file upload.'
                });
            });

            // Handle file removal
            attachmentList.off('click.gigneoPlupload').on('click.gigneoPlupload', '.gn-attachment-remove', function () {
                let fileId = $(this).data('file-id');
                let file = uploader.getFile(fileId);
                if (file) {
                    uploader.removeFile(file);
                    filesToUpload = filesToUpload.filter(f => f.id !== fileId);
                    $(this).closest(`#${file.id}`).fadeOut(100, function () {
                        $(this).remove();
                    });
                }
            });

            // Store uploader instance on the container for external access
            $(`#${containerId}`).data('gn-plupload-instance', uploader);

            // Return filesToUpload and uploader for external use
            return { files: filesToUpload, uploader: uploader };
        }
    };

    //Remove error class
    $(document).on('input', '.gn-input-error', function () {
        $(this).removeClass('gn-input-error');
        let name = $(this).attr('name');
        $('.gn-input-error[name="' + name + '"]').removeClass('gn-input-error');
    });

    /* ===================================
        Modal Popup
    ====================================== */

    //Modal Toggle
    $(document).on('click', '[data-gn-modal-toggle]', function (e) {
        let _this = $(this),
            modal_id = _this.data('gn-modal-toggle'),
            modal = $('#' + modal_id);

        if (modal.length) {
            e.preventDefault();

            $(document).trigger('gigneo_modal_before_open', [_this, modal_id]);

            modal.addClass('gn-active');
            $('body').addClass('gn-modal-open');

            $(document).trigger('gigneo_modal_after_open', [_this, modal_id]);

        }
    });

    //Modal Close
    $(document).on('click', '[data-gn-modal-close]', function (e) {
        let _this = $(this),
            modal_id = _this.data('gn-modal-close'),
            modal = $('#' + modal_id);

        if (modal.length) {
            e.preventDefault();
            modal.removeClass('gn-active');
            $('body').removeClass('gn-modal-open');
            $(document).trigger('gn_modal:closed', [_this, modal_id]);
        }
    });


    /* ===================================
       Dashboard
    ====================================== */

    $(document).ready(function () {

        //Add class to theme option wrapper on load
        $(document).find('.gigneo-theme-option-container').addClass('gn-theme-option-loaded');

        //Select2 Init
        $(document).find('.gn-select2 select').each(function () {
            let _this = $(this);
            _this.select2({
                dropdownParent: _this.parent()
            }).on('change', function (e) {
                if (!e.originalEvent) {
                    let event = new Event('change', { bubbles: true });
                    this.dispatchEvent(event);
                }
            });
        });

        // Observe dynamically added elements
        const observer = new MutationObserver(() => {
            $('.gn-select2 select').not('.select2-hidden-accessible').each(function () {
                $(this).select2({
                    dropdownParent: $(this).parent()
                }).on('change', function (e) {
                    if (!e.originalEvent) {
                        let event = new Event('change', { bubbles: true });
                        this.dispatchEvent(event);
                    }
                });
            });
        });

        observer.observe(document.body, { childList: true, subtree: true });

        //Fields with regex
        $(document).on('input', '.gigneo-theme-option-container input[data-regex],.gigneo-post-meta-container input[data-regex],.gn-term-meta-container input[data-regex]', function () {
            let fieldValue = $(this).val();
            let regexString = $(this).data('regex');
            let regex = new RegExp(regexString);
            if (!regex.test(fieldValue)) {
                let sanitizedValue = fieldValue.split('').filter(char => regex.test(char)).join('');
                $(this).val(sanitizedValue);
            }
        });
    });

    /* ===================================
           Modules
     ====================================== */

    //Module Search
    $('.gn-module-searchbar > input').on('input', function (e) {
        e.preventDefault();
        let _this = $(this);
        let value = _this.val().toLowerCase();
        let modules = $('.gn-module-listing li.gn-module');
        let tabs = $('.gn-module-tabs');

        tabs.find('li').removeClass('active');
        tabs.find('[data-filter="*"]').addClass('active')

        if (value.length > 0) {
            modules.each(function () {
                let title = $(this).find('.gn-title').text().toLowerCase();
                let description = $(this).find('.gn-description').text().toLowerCase();

                if (title.includes(value) || description.includes(value)) {
                    $(this).show();
                } else {
                    $(this).hide();
                }
            });
        } else {
            modules.show();
        }

    });

    //Module tabs
    $('.gn-module-tabs > li').on('click', function (e) {
        e.preventDefault();

        let _this = $(this);
        let filter = _this.data('filter');
        let modules = $('.gn-module-listing > li');
        let search = $('.gn-module-searchbar > input');

        _this.siblings().removeClass('active');
        _this.addClass('active');
        search.val('');

        if (filter !== '*') {
            modules.each(function () {
                let filterValue = $(this).data('type');
                if (filter.includes(filterValue)) {
                    $(this).show();
                } else {
                    $(this).hide();
                }
            });
        } else {
            modules.show();
        }


    });

    //Modules Active/Inactive
    $('.gn-module .gn-checkbox input[type="checkbox"]').on('change', function () {

        let _this = $(this);

        if (_this.is(':disabled') || $('.gn-module-listing').hasClass('gn-loading')) {
            return;
        }

        let module_id = _this.attr('name');
        let is_checked = _this.is(':checked');
        let parent = _this.closest('.gn-checkbox');

        // Disable ALL checkboxes
        $('.gn-module .gn-checkbox input[type="checkbox"]').prop('disabled', true);
        parent.addClass('gn-loading');

        $.ajax({
            url: GigneoBackendCommon.ajax_url,
            type: 'POST',
            data: {
                action: 'gigneo_module_action',
                module_id: module_id,
                status: is_checked ? 'active' : 'inactive',
                security: GigneoBackendCommon.security
            },
            success: function (response) {
                if (response.success) {
                    if (response.data.module_status) {
                        _this.prop('checked', true);
                    } else {
                        _this.prop('checked', false);
                    }
                }
            },
            error: function (xhr, status, error) {
                // revert state on error
                _this.prop('checked', !is_checked);
                const error_message = xhr?.responseJSON?.data?.message || GigneoBackendCommon.went_wrong;
                GigneoAlert.toast({
                    icon: 'error',
                    title: GigneoBackendCommon.error,
                    text: error_message
                });
            },
            complete: function () {
                parent.removeClass('gn-loading');
                $('.gn-module .gn-checkbox input[type="checkbox"]').prop('disabled', false);
            }
        });
    });

    /* ===================================
        Dropdown
    ====================================== */

    $(document).on('click', '.gn-dropdown-toggle', function (e) {
        e.stopPropagation();
        const dropdown = $($(this).data('gn-target'));
        if (dropdown.length) {
            $(this).toggleClass('gn-active');
            dropdown.toggleClass('gn-active');
        }
    });

    // Click outside to close
    $(document).on('click', function (e) {
        // If click is NOT inside dropdown or toggle
        if (!$(e.target).closest('.gn-dropdown-content, .gn-dropdown-toggle').length) {
            $('.gn-dropdown-toggle.gn-active').removeClass('gn-active');
            $('.gn-dropdown-content.gn-active').removeClass('gn-active');
        }
    });

    $(document).on('click', '.gn-dropdown-content.gn-active .gn-dropdown-item', function (e) {
        $('.gn-dropdown-toggle.gn-active').removeClass('gn-active');
        $('.gn-dropdown-content.gn-active').removeClass('gn-active');
    });

    /* ===================================
           Email Verification
     ====================================== */

    $('.gn-email-verification-btn').on('click', function (e) {
        e.preventDefault();
        let _this = $(this);
        let type = _this.data('gn-type');
        let id = _this.data('gn-id');

        GigneoAlert.confirm({
            title: type === 'verified' ? GigneoBackendCommon.email_verified_title : GigneoBackendCommon.email_unverified_title,
            text: type === 'verified' ? GigneoBackendCommon.email_verified_desc : GigneoBackendCommon.email_unverified_desc,
            confirmButtonText: type === 'verified' ? GigneoBackendCommon.unverify : GigneoBackendCommon.verify,
            icon: type === 'verified' ? 'success' : 'error',
            showLoaderOnConfirm: false,
            customClass: {
                confirmButton: type === 'verified' ? 'gn-btn-danger' : 'gn-btn-primary',
            },
            allowOutsideClick: () => !Swal.isLoading(),
            preConfirm: () => {
                let confirmBtn = Swal.getConfirmButton();
                confirmBtn.classList.add('gn-loading');
                confirmBtn.disabled = true;
                let activity_type = type === 'verified' ? 'unverify' : 'verify';
                return new Promise((resolve, reject) => {
                    $.ajax({
                        url: GigneoBackendCommon.ajax_url,
                        method: 'POST',
                        data: {
                            action: 'gigneo_email_verify',
                            id: id,
                            type: activity_type,
                            security: GigneoBackendCommon.security
                        },
                        success: function (response) {
                            confirmBtn.classList.remove('gn-loading');
                            confirmBtn.disabled = false;
                            location.reload();
                            if (response.success) {
                                if (response.data.message) {
                                    GigneoAlert.toast({
                                        icon: 'success',
                                        title: GigneoBackendCommon.success,
                                        text: response.data.message
                                    });
                                }
                            }
                            return Promise.resolve();
                        },
                        error: function (xhr) {
                            confirmBtn.classList.remove('gn-loading');
                            confirmBtn.disabled = false;

                            const error_message = xhr?.responseJSON?.data?.message || GigneoBackendCommon.went_wrong;
                            GigneoAlert.toast({
                                icon: 'error',
                                title: GigneoBackendCommon.error,
                                text: error_message
                            });
                            return Promise.resolve();
                        }
                    });
                });
            }
        });

    });




    /* ===================================
       Account Closed
     ====================================== */

    $('.gn-account-closed-btn').on('click', function (e) {
        e.preventDefault();
        let _this = $(this);
        let id = _this.data('gn-id');

        GigneoAlert.confirm({
            title: GigneoBackendCommon.account_closed,
            text: GigneoBackendCommon.account_closed_desc,
            confirmButtonText: GigneoBackendCommon.reopen,
            icon: 'error',
            showLoaderOnConfirm: false,
            allowOutsideClick: () => !Swal.isLoading(),
            preConfirm: () => {
                let confirmBtn = Swal.getConfirmButton();
                confirmBtn.classList.add('gn-loading');
                confirmBtn.disabled = true;
                return new Promise((resolve, reject) => {
                    $.ajax({
                        url: GigneoBackendCommon.ajax_url,
                        method: 'POST',
                        data: {
                            action: 'gigneo_account_reopen',
                            id: id,
                            security: GigneoBackendCommon.security
                        },
                        success: function (response) {
                            confirmBtn.classList.remove('gn-loading');
                            confirmBtn.disabled = false;
                            location.reload();
                            if (response.success) {
                                if (response.data.message) {
                                    GigneoAlert.toast({
                                        icon: 'success',
                                        title: GigneoBackendCommon.success,
                                        text: response.data.message
                                    });
                                }
                            }
                            return Promise.resolve();
                        },
                        error: function (xhr) {
                            confirmBtn.classList.remove('gn-loading');
                            confirmBtn.disabled = false;

                            const error_message = xhr?.responseJSON?.data?.message || GigneoBackendCommon.went_wrong;
                            GigneoAlert.toast({
                                icon: 'error',
                                title: GigneoBackendCommon.error,
                                text: error_message
                            });
                            return Promise.resolve();
                        }
                    });
                });
            }
        });

    });

    /* ===================================
       Job Block/Unblock
     ====================================== */
     $('#gn-block-job-form').on('submit', function (e) {
        e.preventDefault();

        let _this = $(this);
        let proceed = true;
        let form_data = new FormData(_this[0]);
        form_data.append('action', 'gigneo_block_job');
        form_data.append('security', GigneoBackendCommon.security);

        proceed = GigneoRequiredFormFields.init(_this, proceed);

        if (proceed) {

            _this.parents('.gn-modal-wrapper').removeClass('gn-active');

            GigneoAlert.confirm({
                text: GigneoBackendCommon.block_confirmation_desc,
                confirmButtonText: GigneoBackendCommon.block,
                icon: "error",
                showLoaderOnConfirm: false,
                allowOutsideClick: () => !Swal.isLoading(),
                preConfirm: () => {
                    const confirmBtn = Swal.getConfirmButton();
                    confirmBtn.classList.add('gn-loading');
                    confirmBtn.disabled = true;

                    return new Promise((resolve, reject) => {
                        $.ajax({
                            url: GigneoBackendCommon.ajax_url,
                            method: 'POST',
                            data: form_data,
                            contentType: false,
                            processData: false,
                            success: function (response) {
                                location.reload();
                                confirmBtn.classList.remove('gn-loading');
                                confirmBtn.disabled = false;
                                if (response.success) {
                                    if (response.data.message) {
                                        GigneoAlert.toast({
                                            icon: 'success',
                                            title: GigneoBackendCommon.success,
                                            text: response.data.message
                                        });
                                    }
                                }
                                return Promise.resolve();
                            },
                            error: function (xhr) {
                                confirmBtn.classList.remove('gn-loading');
                                confirmBtn.disabled = false;
                                let error_message = xhr?.responseJSON?.data.message || GigneoBackendCommon.went_wrong;
                                GigneoAlert.toast({
                                    icon: 'error',
                                    title: GigneoBackendCommon.error,
                                    text: error_message
                                });
                                return Promise.resolve();
                            }
                        });
                    });
                }
            });
        }

    });

    $('.gn-unblock-job-btn').on('click', function (e) {
        e.preventDefault();
        let _this = $(this);
        let id = _this.data('gn-id');

        if (!id) {
            return false;
        }

        _this.addClass('gn-loading');
        $.ajax({
            url: GigneoBackendCommon.ajax_url,
            type: 'POST',
            data: {
                action: 'gigneo_unblock_job',
                id: id,
                security: GigneoBackendCommon.security
            },
            success: function (response) {
                location.reload();
                if (response.success) {
                    if (response.data.message) {
                        GigneoAlert.toast({
                            icon: 'success',
                            title: GigneoBackendCommon.success,
                            text: response.data.message
                        });
                    }
                }
            },
            error: function (xhr) {
                const error_message = xhr?.responseJSON?.data?.message || GigneoBackendCommon.went_wrong;
                GigneoAlert.toast({
                    icon: 'error',
                    title: GigneoBackendCommon.error,
                    text: error_message
                });
            }
        });

    });

    /* ===================================
       Service Block/Unblock
     ====================================== */
    $('#gn-block-service-form').on('submit', function (e) {
        e.preventDefault();

        let _this = $(this);
        let proceed = true;
        let form_data = new FormData(_this[0]);
        form_data.append('action', 'gigneo_block_service');
        form_data.append('security', GigneoBackendCommon.security);

        proceed = GigneoRequiredFormFields.init(_this, proceed);

        if (proceed) {

            _this.parents('.gn-modal-wrapper').removeClass('gn-active');

            GigneoAlert.confirm({
                text: GigneoBackendCommon.block_confirmation_desc,
                confirmButtonText: GigneoBackendCommon.block,
                icon: "error",
                showLoaderOnConfirm: false,
                allowOutsideClick: () => !Swal.isLoading(),
                preConfirm: () => {
                    const confirmBtn = Swal.getConfirmButton();
                    confirmBtn.classList.add('gn-loading');
                    confirmBtn.disabled = true;

                    return new Promise((resolve, reject) => {
                        $.ajax({
                            url: GigneoBackendCommon.ajax_url,
                            method: 'POST',
                            data: form_data,
                            contentType: false,
                            processData: false,
                            success: function (response) {
                                location.reload();
                                confirmBtn.classList.remove('gn-loading');
                                confirmBtn.disabled = false;
                                if (response.success) {
                                    if (response.data.message) {
                                        GigneoAlert.toast({
                                            icon: 'success',
                                            title: GigneoBackendCommon.success,
                                            text: response.data.message
                                        });
                                    }
                                }
                                return Promise.resolve();
                            },
                            error: function (xhr) {
                                confirmBtn.classList.remove('gn-loading');
                                confirmBtn.disabled = false;
                                let error_message = xhr?.responseJSON?.data.message || GigneoBackendCommon.went_wrong;
                                GigneoAlert.toast({
                                    icon: 'error',
                                    title: GigneoBackendCommon.error,
                                    text: error_message
                                });
                                return Promise.resolve();
                            }
                        });
                    });
                }
            });
        }

    });

    $('.gn-unblock-service-btn').on('click', function (e) {
        e.preventDefault();
        let _this = $(this);
        let id = _this.data('gn-id');

        if (!id) {
            return false;
        }

        _this.addClass('gn-loading');
        $.ajax({
            url: GigneoBackendCommon.ajax_url,
            type: 'POST',
            data: {
                action: 'gigneo_unblock_service',
                id: id,
                security: GigneoBackendCommon.security
            },
            success: function (response) {
                location.reload();
                if (response.success) {
                    if (response.data.message) {
                        GigneoAlert.toast({
                            icon: 'success',
                            title: GigneoBackendCommon.success,
                            text: response.data.message
                        });
                    }
                }
            },
            error: function (xhr) {
                const error_message = xhr?.responseJSON?.data?.message || GigneoBackendCommon.went_wrong;
                GigneoAlert.toast({
                    icon: 'error',
                    title: GigneoBackendCommon.error,
                    text: error_message
                });
            }
        });

    });


    /* ===================================
           Layout Builder
     ====================================== */

    //Status update
    $('.gn-layout-status-switch input.gn-status-input').on('change', function (e) {
        e.preventDefault();
        let _this = $(this);
        let status = _this.is(':checked') ? 'yes' : 'no';
        let post_id = _this.data('post-id');
        let parent = _this.parents('.gn-layout-status-switch');

        if (_this.is(':disabled')) {
            return;
        }

        parent.addClass('gn-loading');

        $.ajax({
            url: GigneoBackendCommon.ajax_url,
            type: 'POST',
            data: {
                action: 'gigneo_layout_status',
                post_id: post_id,
                status: status,
                security: GigneoBackendCommon.security
            },
            success: function (response) {
                if (response.success) {
                    parent.removeClass('gn-loading');
                    location.reload();
                }
            },
            error: function (xhr, status, error) {
                console.error(error);
            }
        });

    });

    /* ===================================
           Service Approve / Reject
     ====================================== */

    //Approve service
    $('.gn-service-approve-btn').on('click', function (e) {
        e.preventDefault();
        let _this = $(this);
        let id = _this.data('gn-id');

        _this.addClass('gn-loading');

        $.ajax({
            url: GigneoBackendCommon.ajax_url,
            method: 'POST',
            data: {
                action: 'gigneo_approve_service',
                id: id,
                security: GigneoBackendCommon.security
            },
            success: function (response) {
                location.reload();
                if (response.success && response.data.message) {
                    GigneoAlert.toast({
                        icon: 'success',
                        title: GigneoBackendCommon.success,
                        text: response.data.message
                    });
                }
            },
            error: function (xhr) {
                _this.removeClass('gn-loading');
                const error_message = xhr?.responseJSON?.data?.message || GigneoBackendCommon.went_wrong;
                GigneoAlert.toast({
                    icon: 'error',
                    title: GigneoBackendCommon.error,
                    text: error_message
                });
            }
        });

    });

    //Rejection modal open
    $(document).on('gigneo_modal_before_open', function (e, _this, modal_id) {
        let selector = $('#' + modal_id);
        if (selector.hasClass('gn-reject-service-modal')) {
            let id = _this.data('gn-id') || '';
            selector.find('input[name="service_id"]').val(id);
        }
    });

    //Rejection modal before open
    $(document).on('gigneo_modal_before_open', function (e, _this, modal_id) {
        let selector = $('#' + modal_id);
        if (selector.hasClass('gn-reject-service-modal')) {
            let id = _this.data('gn-id') || '';
            selector.find('input[name="service_id"]').val(id);
        }
    });

    //Change rejection type
    $('input[name="rejection_type"]').on('change', function (e) {
        e.preventDefault();
        let _this = $(this);
        let fields = _this.parents('form');
        let val = _this.val();

        if ('soft' === val) {
            fields.find('.gn-form-field.gn-request-changes').removeClass('d-none');
            fields.find('.gn-form-field.gn-rejection-detail').addClass('d-none');
            fields.find('[name="rejection_detail"]').removeClass('gn-required-field').addClass('gn-not-required-field');
            fields.find('[name="request_changes"]').removeClass('gn-not-required-field').addClass('gn-required-field');
        } else {
            fields.find('.gn-form-field.gn-rejection-detail').removeClass('d-none');
            fields.find('.gn-form-field.gn-request-changes').addClass('d-none');
            fields.find('[name="rejection_detail"]').removeClass('gn-not-required-field').addClass('gn-required-field');
            fields.find('[name="request_changes"]').removeClass('gn-required-field').addClass('gn-not-required-field');
        }

    });

    //Reject Service
    $(document).on('submit', '#gn-service-reject-form', function (e) {
        e.preventDefault();
        let _this = $(this);
        let form_data = new FormData(_this[0]);
        form_data.append('action', 'gigneo_reject_service');
        form_data.append('security', GigneoBackendCommon.security);
        let proceed = true;

        //Fields input validation
        proceed = window.GigneoRequiredFormFields.init(_this, proceed);

        if (proceed) {
            _this.find('button[type="submit"]').addClass("gn-loading");
            $.ajax({
                url: GigneoBackendCommon.ajax_url,
                method: 'POST',
                data: form_data,
                contentType: false,
                processData: false,
                success: function (response) {
                    location.reload();
                    _this.find('button[type="submit"]').removeClass("gn-loading");
                    if (response.success) {
                        GigneoAlert.toast({
                            icon: 'success',
                            title: GigneoBackendCommon.success,
                            text: response.data.message
                        });
                    }
                },

                error: function (xhr, status, error) {
                    _this.find('button[type="submit"]').removeClass("gn-loading");
                    let error_message = xhr?.responseJSON?.data?.message || GigneoBackendCommon.went_wrong;
                    GigneoAlert.toast({
                        icon: 'error',
                        text: error_message
                    });
                },
            });
        }
    });

    /* ===================================
       Job Approve / Reject
     ====================================== */

    //Approve service
    $('.gn-job-approve-btn').on('click', function (e) {
        e.preventDefault();
        let _this = $(this);
        let id = _this.data('gn-id');

        _this.addClass('gn-loading');

        $.ajax({
            url: GigneoBackendCommon.ajax_url,
            method: 'POST',
            data: {
                action: 'gigneo_approve_job',
                id: id,
                security: GigneoBackendCommon.security
            },
            success: function (response) {
                location.reload();
                if (response.success && response.data.message) {
                    GigneoAlert.toast({
                        icon: 'success',
                        title: GigneoBackendCommon.success,
                        text: response.data.message
                    });
                }
            },
            error: function (xhr) {
                _this.removeClass('gn-loading');
                const error_message = xhr?.responseJSON?.data?.message || GigneoBackendCommon.went_wrong;
                GigneoAlert.toast({
                    icon: 'error',
                    title: GigneoBackendCommon.error,
                    text: error_message
                });
            }
        });

    });

    //Rejection modal open
    $(document).on('gigneo_modal_before_open', function (e, _this, modal_id) {
        let selector = $('#' + modal_id);
        if (selector.hasClass('gn-reject-job-modal')) {
            let id = _this.data('gn-id') || '';
            selector.find('input[name="job_id"]').val(id);
        }
    });

    //Rejection modal before open
    $(document).on('gigneo_modal_before_open', function (e, _this, modal_id) {
        let selector = $('#' + modal_id);
        if (selector.hasClass('gn-reject-job-modal')) {
            let id = _this.data('gn-id') || '';
            selector.find('input[name="job_id"]').val(id);
        }
    });

    //Reject Job
    $(document).on('submit', '#gn-job-reject-form', function (e) {
        e.preventDefault();
        let _this = $(this);
        let form_data = new FormData(_this[0]);
        form_data.append('action', 'gigneo_reject_job');
        form_data.append('security', GigneoBackendCommon.security);
        let proceed = true;

        //Fields input validation
        proceed = window.GigneoRequiredFormFields.init(_this, proceed);

        if (proceed) {
            _this.find('button[type="submit"]').addClass("gn-loading");
            $.ajax({
                url: GigneoBackendCommon.ajax_url,
                method: 'POST',
                data: form_data,
                contentType: false,
                processData: false,
                success: function (response) {
                    location.reload();
                    _this.find('button[type="submit"]').removeClass("gn-loading");
                    if (response.success) {
                        GigneoAlert.toast({
                            icon: 'success',
                            title: GigneoBackendCommon.success,
                            text: response.data.message
                        });
                    }
                },

                error: function (xhr, status, error) {
                    _this.find('button[type="submit"]').removeClass("gn-loading");
                    let error_message = xhr?.responseJSON?.data?.message || GigneoBackendCommon.went_wrong;
                    GigneoAlert.toast({
                        icon: 'error',
                        text: error_message
                    });
                },
            });
        }
    });



    /* ===================================
       Invoices
   ====================================== */

    $(document).on('click', '.gn-invoice-action .gn-invoice-download', function (e) {
        e.preventDefault();
        let _this = $(this);
        let invoice_id = _this.data('gn-invoice-id');

        if (invoice_id === '') {
            return false;
        }

        _this.addClass('gn-loading');

        $.ajax({
            url: GigneoBackendCommon.ajax_url,
            method: 'POST',
            data: {
                action: 'gigneo_moderator_invoice_download',
                id: invoice_id,
                security: GigneoBackendCommon.security
            },
            success: function (response) {
                _this.removeClass('gn-loading');
                if (response.data.file_data && response.data.file_name) {
                    const byteCharacters = atob(response.data.file_data);
                    const byteNumbers = new Array(byteCharacters.length);
                    for (let i = 0; i < byteCharacters.length; i++) {
                        byteNumbers[i] = byteCharacters.charCodeAt(i);
                    }
                    const byteArray = new Uint8Array(byteNumbers);
                    const blob = new Blob([byteArray], { type: 'application/pdf' });
                    const url = window.URL.createObjectURL(blob);

                    const a = document.createElement('a');
                    a.href = url;
                    a.download = response.data.file_name;
                    document.body.appendChild(a);
                    a.click();
                    document.body.removeChild(a);
                    window.URL.revokeObjectURL(url);
                } else {
                    GigneoAlert.toast({
                        icon: 'error', title: GigneoBackendCommon.error, text: GigneoBackendCommon.went_wrong
                    });
                }
            }, error: function (xhr, status, error) {
                _this.removeClass('gn-loading');
                let error_message = xhr?.responseJSON?.data.message || GigneoBackendCommon.went_wrong;
                GigneoAlert.toast({
                    icon: 'error', title: GigneoBackendCommon.error, text: error_message
                });
            }
        });

    });

    /* ===================================
           User Profiles
     ====================================== */

    $('.gn-create-freelancer-profile').on('click', function (e) {
        e.preventDefault();
        let _this = $(this);
        let id = _this.data('gn-id');

        GigneoAlert.confirm({
            text: GigneoBackendCommon.create_freelancer_profile_desc,
            confirmButtonText: GigneoBackendCommon.create,
            icon: 'warning',
            showLoaderOnConfirm: false,
            customClass: {
                confirmButton: 'gn-btn-primary',
            },
            allowOutsideClick: () => !Swal.isLoading(),
            preConfirm: () => {
                let confirmBtn = Swal.getConfirmButton();
                confirmBtn.classList.add('gn-loading');
                confirmBtn.disabled = true;
                let form_data = new FormData();
                form_data.append('action', 'gigneo_create_user_profile');
                form_data.append('id', id);
                form_data.append('type', 'freelancer');
                form_data.append('security', GigneoBackendCommon.security);
                return new Promise((resolve, reject) => {
                    $.ajax({
                        url: GigneoBackendCommon.ajax_url,
                        method: 'POST',
                        data: form_data,
                        contentType: false,
                        processData: false,
                        success: function (response) {
                            confirmBtn.classList.remove('gn-loading');
                            confirmBtn.disabled = false;
                            location.reload();
                            if (response.success) {
                                if (response.data.message) {
                                    GigneoAlert.toast({
                                        icon: 'success',
                                        title: GigneoBackendCommon.success,
                                        text: response.data.message
                                    });
                                }
                            }
                            return Promise.resolve();
                        },
                        error: function (xhr) {
                            confirmBtn.classList.remove('gn-loading');
                            confirmBtn.disabled = false;

                            const error_message = xhr?.responseJSON?.data?.message || GigneoBackendCommon.went_wrong;
                            GigneoAlert.toast({
                                icon: 'error',
                                title: GigneoBackendCommon.error,
                                text: error_message
                            });
                            return Promise.resolve();
                        }
                    });
                });
            }
        });

    });

    $('.gn-create-employer-profile').on('click', function (e) {
        e.preventDefault();
        let _this = $(this);
        let id = _this.data('gn-id');

        GigneoAlert.confirm({
            text: GigneoBackendCommon.create_employer_profile_desc,
            confirmButtonText: GigneoBackendCommon.create,
            icon: 'warning',
            showLoaderOnConfirm: false,
            customClass: {
                confirmButton: 'gn-btn-primary',
            },
            allowOutsideClick: () => !Swal.isLoading(),
            preConfirm: () => {
                let confirmBtn = Swal.getConfirmButton();
                confirmBtn.classList.add('gn-loading');
                confirmBtn.disabled = true;
                let form_data = new FormData();
                form_data.append('action', 'gigneo_create_user_profile');
                form_data.append('id', id);
                form_data.append('type', 'employer');
                form_data.append('security', GigneoBackendCommon.security);
                return new Promise((resolve, reject) => {
                    $.ajax({
                        url: GigneoBackendCommon.ajax_url,
                        method: 'POST',
                        data: form_data,
                        contentType: false,
                        processData: false,
                        success: function (response) {
                            confirmBtn.classList.remove('gn-loading');
                            confirmBtn.disabled = false;
                            location.reload();
                            if (response.success) {
                                if (response.data.message) {
                                    GigneoAlert.toast({
                                        icon: 'success',
                                        title: GigneoBackendCommon.success,
                                        text: response.data.message
                                    });
                                }
                            }
                            return Promise.resolve();
                        },
                        error: function (xhr) {
                            confirmBtn.classList.remove('gn-loading');
                            confirmBtn.disabled = false;

                            const error_message = xhr?.responseJSON?.data?.message || GigneoBackendCommon.went_wrong;
                            GigneoAlert.toast({
                                icon: 'error',
                                title: GigneoBackendCommon.error,
                                text: error_message
                            });
                            return Promise.resolve();
                        }
                    });
                });
            }
        });

    });

    /* ===================================
        Withdrawals
    ====================================== */

    //withdrawal action
    $(document).on('click', '.gn-withdraw-submit', function () {

        let _this = $(this);
        let proceed = true;
        let withdrawal_id = parseInt(_this.data('gn-withdrawal-id')) || '';
        let withdrawal_action = _this.parents('.gn-modal-wrapper').find('#gn-respond-action-' + withdrawal_id).val() || '';
        let withdrawal_note = _this.parents('.gn-modal-wrapper').find('#gn-withdrawal-note-' + withdrawal_id).val() || '';
        proceed = window.GigneoRequiredFormFields.init(_this.parents('.gn-modal-wrapper'), proceed);
        if (!proceed) {
            return false;
        }
        _this.addClass('gn-loading');

        $.ajax({
            url: GigneoBackendCommon.ajax_url,
            method: 'POST',
            data: {
                action: 'gigneo_withdrawal_action',
                security: GigneoBackendCommon.security,
                withdrawal_id: withdrawal_id,
                withdrawal_action: withdrawal_action,
                withdrawal_note: withdrawal_note,
            },
            success: function (response) {
                _this.removeClass('gn-loading');
                if (response.success && response.data.message) {
                    GigneoAlert.toast({
                        icon: 'success',
                        title: GigneoBackendCommon.success,
                        text: response.data.message
                    });
                }
                location.reload();
            },
            error: function (xhr) {
                _this.removeClass('gn-loading');
                let error_message = xhr?.responseJSON?.data?.message || GigneoBackendCommon.went_wrong;
                GigneoAlert.toast({
                    icon: 'error',
                    title: GigneoBackendCommon.error,
                    text: error_message
                });
                location.reload();
            }
        });
    });

    /* ===================================
        Services
    ====================================== */

    $('body.post-type-gigneo_service #taxonomy-gigneo_facet input').on('change', function () {
        alert(GigneoBackendCommon.facet_change || 'You changed the categories. Please save and reload the page to update plan features fields.');
    });


}(jQuery));
