(function ($) {
    "use strict";

    /* ===================================
        Listing
     ====================================== */

    // Service Filter
    $('#gn-service-filters .gn-filter').on('click', function (e) {
        e.preventDefault();

        let _this = $(this);

        _this.addClass('gn-active').siblings().removeClass('gn-active');

        applyServiceFilters();
    });

    //Search Service
    $('input#gn-search-service-input').on('keyup', function () {
        applyServiceFilters();
    });

    function applyServiceFilters() {
        let keyword = $('#gn-search-service-input').val().toLowerCase();
        let activeFilter = $('#gn-service-filters .gn-filter.gn-active').data('gn-filter');

        let services = $('.gn-service-listing');
        let items = services.find('.gn-service-listing-item');

        let visibleCount = 0;

        items.each(function () {
            let $item = $(this);

            let titleVal = $item
                .find('.gn-title')
                .html()
                .toLowerCase();

            // Search match
            let searchMatch = !keyword || titleVal.includes(keyword);

            // Filter match
            let filterMatch = !activeFilter || activeFilter === '*' || $item.hasClass(activeFilter);

            let show = searchMatch && filterMatch;

            $item.toggle(show);

            if (show) {
                visibleCount++;
            }
        });

        // Toggle no-services class
        if (visibleCount === 0) {
            services.addClass('gn-no-services');
        } else {
            services.removeClass('gn-no-services');
        }
    }

    // Clone Service
    $('.gn-clone-service').on('click', function (e) {
        e.preventDefault();
        const _this = $(this);
        const service_id = _this.data('gn-id');

        if (service_id === undefined || service_id === '') {
            return false;
        }

        _this.prop('disabled', true).addClass('gn-loading');

        $.ajax({
            url: GigneoCommon.ajax_url,
            method: 'POST',
            data: {
                action: 'gigneo_service_clone',
                id: service_id,
                security: GigneoCommon.security,
            },
            success: function (response) {
                if (response.success && response.data.redirect_url) {
                    window.location.href = response.data.redirect_url;
                }
                _this.prop('disabled', false).removeClass('gn-loading');
            },
            error: function (response) {
                _this.prop('disabled', false).removeClass('gn-loading');
                GigneoAlert.toast({
                    icon: 'error',
                    title: GigneoCommon.error,
                    text: response.responseJSON && response.responseJSON.data && response.responseJSON.data.message ? response.responseJSON.data.message : ''
                });
            },
        });
    });

    //Pause/Active service
    $('.gn-update-service-status').on('click', function (e) {
        e.preventDefault();
        let _this = $(this);
        let service_id = _this.data("gn-id");
        let service_status = _this.data("gn-status");
        let confirmationText = service_status === 'publish'
            ? GigneoCommon.active_confirmation_desc
            : GigneoCommon.pause_confirmation_desc;

        GigneoAlert.confirm({
            title: GigneoCommon.confirmation_title,
            text: confirmationText,
            confirmButtonText: GigneoCommon.confirm,
            icon: "warning",
            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: GigneoCommon.ajax_url,
                        method: 'POST',
                        data: {
                            action: 'gigneo_pause_active_service',
                            id: service_id,
                            status: service_status,
                            security: GigneoCommon.security,
                        },
                        success: function (response) {
                            if (response.success) {
                                // Redirect to edit page of the new service
                                if (response.data.message) {
                                    GigneoAlert.toast({
                                        icon: 'success',
                                        title: GigneoCommon.success,
                                        text: response.data.message
                                    });
                                }
                                window.location.reload();
                            } else {
                                GigneoAlert.toast({
                                    icon: 'error',
                                    title: GigneoCommon.error,
                                    text: response.data && response.data.message ? response.data.message : ''
                                });
                            }
                        },
                        error: function (response) {
                            GigneoAlert.toast({
                                icon: 'error',
                                title: GigneoCommon.error,
                                text: response.responseJSON && response.responseJSON.data && response.responseJSON.data.message ? response.responseJSON.data.message : ''
                            });
                        }
                    });
                });
            }
        });

    });

    //Featured service
    $('.gn-featured-service').on('click', function (e) {
        e.preventDefault();
        let _this = $(this);
        let service_id = _this.data("gn-id");
        let service_action = _this.data("gn-featured");
        let confirmationText = service_action ? GigneoCommon.featured_confirmation_desc : GigneoCommon.removed_featured_confirmation_desc;

        GigneoAlert.confirm({
            title: GigneoCommon.confirmation_title,
            text: confirmationText,
            confirmButtonText: GigneoCommon.confirm,
            icon: "warning",
            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: GigneoCommon.ajax_url,
                        method: 'POST',
                        data: {
                            action: 'gigneo_featured_service',
                            id: service_id,
                            featured: service_action,
                            security: GigneoCommon.security,
                        },
                        success: function (response) {
                            if (response.success) {
                                // Redirect to edit page of the new service
                                if (response.data.message) {
                                    GigneoAlert.toast({
                                        icon: 'success',
                                        title: GigneoCommon.success,
                                        text: response.data.message
                                    });
                                }
                                window.location.reload();
                            } else {
                                GigneoAlert.toast({
                                    icon: 'error',
                                    title: GigneoCommon.error,
                                    text: response.data && response.data.message ? response.data.message : ''
                                });
                            }
                        },
                        error: function (response) {
                            GigneoAlert.toast({
                                icon: 'error',
                                title: GigneoCommon.error,
                                text: response.responseJSON && response.responseJSON.data && response.responseJSON.data.message ? response.responseJSON.data.message : ''
                            });
                        }
                    });
                });
            }
        });

    });

    //Service Remove
    $('.gn-remove-service').on('click', function (e) {
        e.preventDefault();
        let _this = $(this);
        let service_id = _this.data("gn-id");

        GigneoAlert.confirm({
            title: GigneoCommon.confirmation_title,
            text: GigneoCommon.delete_confirmation_desc,
            confirmButtonText: GigneoCommon.delete,
            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: GigneoCommon.ajax_url,
                        method: 'POST',
                        data: {
                            action: 'gigneo_remove_service',
                            id: service_id,
                            security: GigneoCommon.security,
                        },
                        success: function (response) {
                            if (response.success) {
                                // Redirect to edit page of the new service
                                if (response.data.message) {
                                    GigneoAlert.toast({
                                        icon: 'success',
                                        title: GigneoCommon.success,
                                        text: response.data.message
                                    });
                                }
                                window.location.reload();
                            } else {
                                GigneoAlert.toast({
                                    icon: 'error',
                                    title: GigneoCommon.error,
                                    text: response.data && response.data.message ? response.data.message : ''
                                });
                            }
                        },
                        error: function (response) {
                            GigneoAlert.toast({
                                icon: 'error',
                                title: GigneoCommon.error,
                                text: response.responseJSON && response.responseJSON.data && response.responseJSON.data.message ? response.responseJSON.data.message : ''
                            });
                        }
                    });
                });
            }
        });

    });

    //Service Draft
    $('.gn-draft-service').on('click', function (e) {
        e.preventDefault();
        let _this = $(this);
        let service_id = _this.data("gn-id");

        GigneoAlert.confirm({
            title: GigneoCommon.confirmation_title,
            text: GigneoCommon.draft_confirmation_desc,
            confirmButtonText: GigneoCommon.draft,
            icon: "warning",
            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: GigneoCommon.ajax_url,
                        method: 'POST',
                        data: {
                            action: 'gigneo_draft_service',
                            id: service_id,
                            security: GigneoCommon.security,
                        },
                        success: function (response) {
                            if (response.success) {
                                // Redirect to edit page of the new service
                                if (response.data.message) {
                                    GigneoAlert.toast({
                                        icon: 'success',
                                        title: GigneoCommon.success,
                                        text: response.data.message
                                    });
                                }
                                window.location.reload();
                            } else {
                                GigneoAlert.toast({
                                    icon: 'error',
                                    title: GigneoCommon.error,
                                    text: response.data && response.data.message ? response.data.message : ''
                                });
                            }
                        },
                        error: function (response) {
                            GigneoAlert.toast({
                                icon: 'error',
                                title: GigneoCommon.error,
                                text: response.responseJSON && response.responseJSON.data && response.responseJSON.data.message ? response.responseJSON.data.message : ''
                            });
                        }
                    });
                });
            }
        });

    });

    //Service Card Media Slider
    $('.gn-service-media-slider').slick({
        dots: true,
        arrows: true,
        infinite: false,
        speed: 300,
        slidesToShow: 1,
        slidesToScroll: 1,
        rtl: $('html').attr('dir') === 'rtl'
    });

    // Service Sidebar Toggle
    jQuery(document).on('ready', function () {
        function initToggle() {
            if (jQuery(window).width() <= 991) {

                jQuery('.gn-service-edit-step .gn-aside .gn-aside-body').hide();

                jQuery('.gn-service-edit-step .gn-aside .gn-aside-content > .gn-title')
                    .off('click')
                    .on('click', function () {

                        var $this = jQuery(this);

                        $this.toggleClass('gn-active');
                        $this.next('.gn-aside-body').slideToggle(300);

                    });

            } else {

                jQuery('.gn-service-edit-step .gn-aside .gn-aside-body').show();
                jQuery('.gn-service-edit-step .gn-aside .gn-aside-content > .gn-title')
                    .removeClass('gn-active') // reset class
                    .off('click');
            }
        }

        initToggle();

        jQuery(window).on('resize', function () {
            initToggle();
        });

    });

    /* ===================================
        Add / Edit Service
     ====================================== */

    if ($('.gn-service-edit-wrapper').length) {

        //Category change
        $(document).on('change', '.gn-service-edit-wrapper #gn-service-category', function () {
            let _this = $(this);
            let category = _this.val();
            let sub_selector = _this.parents('.gn-form-fields').find('#gn-service-subcategory');
            let service_type = $('#gn-service-specific-types');

            sub_selector.empty();

            if (category && GigneoDashboard.sub_categories[category] !== undefined) {
                sub_selector.removeAttr('disabled');
                service_type.attr('disabled', true);
                service_type.empty();

                let sub_categories = GigneoDashboard.sub_categories[category];

                sub_selector.append(
                    $('<option>', {
                        value: '',
                        text: GigneoDashboard.default_sub_categories
                    })
                );

                Object.entries(sub_categories).forEach(function ([value, label]) {
                    sub_selector.append(
                        $('<option>')
                            .val(value)
                            .html(label)
                    );
                });

                sub_selector.trigger('change.select2');
            }

        });

        //Sub Category change
        $(document).on('change', '.gn-service-edit-wrapper #gn-service-subcategory', function () {
            let _this = $(this);
            let category = _this.val();
            let specific_types = _this.parents('.gn-form-fields').find('#gn-service-specific-types');

            specific_types.empty();

            if (category && GigneoDashboard.sub_categories[category] !== undefined) {
                specific_types.removeAttr('disabled');
                let sub_categories = GigneoDashboard.sub_categories[category];

                Object.entries(sub_categories).forEach(function ([value, label]) {
                    specific_types.append(
                        $('<option>')
                            .val(value)
                            .html(label)
                    );
                });

                specific_types.trigger('change.select2');
            }

        });

        function TinymceInit() {
            if (typeof tinymce === 'undefined') {
                return;
            }
            if (tinymce.get('gn-description')) {
                tinymce.get('gn-description').remove();
                tinymce.init({
                    selector: '#gn-description',
                    toolbar: 'bold italic bullist numlist link unlink',
                    plugins: 'lists link',
                    resize: false,
                    menubar: false,
                    branding: false,
                    content_style: 'body { font-size: 14px; background-color: transparent; font-family: var(--gigneo-primary-font,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji) }',
                    content_css: GigneoDashboard.tinymce_skin,
                });
            }
        }

        //Save for service form
        $(document).on('click', '.gn-service-save', function (e) {
            e.preventDefault();

            let btn = $(this);
            let type = btn.data('gn-type');
            let step_selector = $('.gn-service-edit-steps .gn-current-step');
            let step_keys = Object.keys(step_selector.data('gn-steps'));
            let step = btn.data('gn-step');
            let next_step = btn.data('gn-next-step');
            let prev_step = btn.data('gn-prev-step');
            let redirect_url = btn.data('gn-redirect-url');
            let form = btn.closest('#gn-service-form-' + step);

            // Force TinyMCE editors to save content to textarea
            if (typeof tinyMCE !== 'undefined') {
                tinyMCE.triggerSave();
            }

            let url = new URL(window.location.href);
            let params = new URLSearchParams(url.search);

            let id = params.get('p_id');
            let form_data = new FormData(form[0]);
            form_data.append('action', 'gigneo_save_service');
            form_data.append('step', step);
            form_data.append('id', id);
            form_data.append('type', type);
            form_data.append('security', GigneoCommon.security);
            let proceed = true;
            let submitBtn = btn;

            proceed = window.GigneoRequiredFormFields.init(form, proceed);

            if (proceed) {
                submitBtn.addClass('gn-loading').prop('disabled', true);

                $.ajax({
                    url: GigneoCommon.ajax_url,
                    method: 'POST',
                    data: form_data,
                    contentType: false,
                    processData: false,
                    success: function (response) {
                        if (response.success) {

                            if (type === 'draft' || type === 'redirect') {
                                window.location.href = redirect_url;
                                return;
                            }

                            if (response?.data?.id !== undefined) {
                                params.set('p_id', response.data.id);
                            }

                            if (type === 'publish') {
                                let publish_modal = $('#gn-service-publish')
                                publish_modal.addClass('gn-active');
                            }

                            if (next_step) {

                                params.set('step', next_step);

                                if (response.data.features && '' !== response.data.features) {
                                    let features = response.data.features;

                                    if (features) {
                                        let features_selector = $(features);
                                        let features_target = $('#gn-edit-service-features');

                                        features_target.html(features_selector.html()).toggleClass('d-none', features_selector.hasClass('d-none'));
                                    }
                                }

                                if (response.data.details && '' !== response.data.details) {
                                    let details_html = $(response.data.details).html();
                                    $('#gn-service-edit-details').html(details_html);
                                    TinymceInit();
                                    window.GigneoSelect2.init();
                                    window.GigneoGoogleMap?.init();
                                }

                                $('.gn-service-edit-' + step).addClass('d-none');
                                $('.gn-service-edit-' + next_step).removeClass('d-none');
                                $('.gn-service-edit-steps [data-gn-step="' + step + '"]').removeClass('gn-active');
                                $('.gn-service-edit-steps [data-gn-step="' + next_step + '"]').addClass('gn-active');
                                step_selector.html(step_keys.indexOf(next_step) + 1);
                            }

                            url.search = params.toString();
                            window.history.replaceState({}, '', url.toString());
                            window.GigneoSelect2.init();
                            window.GigneoGoogleMap?.init();

                        } else {
                            GigneoAlert.toast({
                                icon: 'error',
                                title: GigneoCommon.error,
                                text: response.data.message
                            });
                        }
                    },
                    error: function (response) {
                        GigneoAlert.toast({
                            icon: 'error',
                            title: GigneoCommon.error,
                            text: response.responseJSON.data.message
                        });
                    },
                    complete: function () {
                        submitBtn.prop('disabled', false);
                        submitBtn.removeClass('gn-loading');
                    }
                });
            }
        });

        //Back button functionality
        $(document).on('click', '.gn-service-back', function (e) {
            e.preventDefault();
            let btn = $(this);
            let step_selector = $('.gn-service-edit-steps .gn-current-step');
            let step_keys = Object.keys(step_selector.data('gn-steps'));
            let step = btn.data('gn-step');
            let prev_step = btn.data('gn-prev-step');
            if (!prev_step) {
                return;
            }

            let url = new URL(window.location.href);
            let params = new URLSearchParams(url.search);

            params.set('step', prev_step);

            url.search = params.toString();
            window.history.replaceState({}, '', url.toString());

            $('.gn-service-edit-' + step).addClass('d-none');
            $('.gn-service-edit-' + prev_step).removeClass('d-none');
            $('.gn-service-edit-steps [data-gn-step="' + step + '"]').removeClass('gn-active');
            $('.gn-service-edit-steps [data-gn-step="' + prev_step + '"]').addClass('gn-active');
            step_selector.html(step_keys.indexOf(prev_step) + 1);

        });

        //Plan Tiers
        $(document).on('change', '#gn-pricing-tier-switch', function () {
            let isChecked = this.checked;
            let wrapper = $('#gn-service-edit-pricing');

            let tierFields = wrapper.find(
                '.gn-tab-content-plan-standard .gn-not-required-field, ' +
                '.gn-tab-content-plan-premium .gn-not-required-field, ' +
                '.gn-tab-content-plan-standard .gn-required-field, ' +
                '.gn-tab-content-plan-premium .gn-required-field'
            );

            wrapper.toggleClass('gn-show-plan-tiers', isChecked);

            // Toggle required / not-required fields
            tierFields.toggleClass('gn-required-field', isChecked).toggleClass('gn-not-required-field', !isChecked);

            // Always switch back to Basic tab
            $('.gn-plan-tier-tabs > .gn-tab-plan-basic').trigger('click');
        });

        //Tiers Tabs
        $(document).on('click', '#gn-service-form-pricing .gn-plan-tier-tabs .gn-tab', function (e) {
            e.preventDefault();

            let _this = $(this);
            let tab_content_id = _this.data('gn-tab-content');
            let tab_content = $(`.gn-tab-content-${tab_content_id}`);

            if (tab_content.length) {
                $('#gn-service-form-pricing .gn-plan-tier-tabs > .gn-tab').removeClass('gn-active');
                $('#gn-service-form-pricing .gn-plan-tier-tabs-content > .gn-tab-content').removeClass('gn-active');
                _this.addClass('gn-active');
                tab_content.addClass('gn-active');
            }
        });

        //Add Custom Offer
        $(document).on('click', '.gn-add-custom-offer', function (e) {
            e.preventDefault();

            let _this = $(this);
            let wrapper = $('#gn-edit-service-offers');
            let offer_count = $(document).find('.gn-plan-tier-tabs-info .gn-plan-field-offer').length;

            let offer_input_template = wp.template('gn-custom-offer-input');
            let offer_input_html = offer_input_template({ index: offer_count });

            let offer_plan_checkbox = wp.template('gn-custom-offer-checkbox');
            let offer_plan_one_checkbox = offer_plan_checkbox({ index: offer_count, plan: 'one' });
            let offer_plan_two_checkbox = offer_plan_checkbox({ index: offer_count, plan: 'two' });
            let offer_plan_three_checkbox = offer_plan_checkbox({ index: offer_count, plan: 'three' });

            wrapper.find('.gn-plan-tier-tabs-info .gn-form-fields').append(offer_input_html);

            wrapper.find('.gn-tab-content-plan-basic .gn-form-fields').append(offer_plan_one_checkbox);
            wrapper.find('.gn-tab-content-plan-standard .gn-form-fields').append(offer_plan_two_checkbox);
            wrapper.find('.gn-tab-content-plan-premium .gn-form-fields').append(offer_plan_three_checkbox);

        });

        //Remove Custom Offer
        $(document).on('click', '.gn-remove-custom-offer', function (e) {
            e.preventDefault();

            let _this = $(this);
            let field = _this.data('gn-offer-id');
            if (field !== '') {
                $(document).find(`.gn-plan-field-offer-${field}`).remove();
            }
        });

        //Add Custom Addon
        $(document).on('click', '.gn-add-custom-addon', function (e) {
            e.preventDefault();

            let _this = $(this);
            let wrapper = $('#gn-edit-service-addons');
            let addon_count = $(document).find('.gn-custom-addons .gn-custom-addon').length;

            let addon_template = wp.template('gn-custom-addon');
            let addon_html = addon_template({ index: addon_count });

            wrapper.find('.gn-custom-addons').append(addon_html);

            window.GigneoSelect2.init();

        });

        //Remove Custom Addon
        $(document).on('click', '.gn-remove-custom-addon', function (e) {
            e.preventDefault();

            let _this = $(this);
            let addon_id = _this.data('gn-addon-id');
            if (addon_id !== '') {
                $(document).find(`#gn-custom-addon-${addon_id}`).remove();
            }
        });

        //Delivery Type
        $(document).on('change', '.gn-onsite-delivery-type input[name="delivery_type"]', function () {
            let delivery_type = $(this).val();
            let location = $('#gn-edit-service-locations');
            let location_form = $('#gn-save-service-location-form');
            let max_radius = location.find('.gn-max-radius');
            if ('visit_me' === delivery_type) {
                max_radius.addClass('d-none');
                location_form.find('.gn-map-field-wrapper').removeClass('col-md-6').addClass('col-md-12');
                location_form.find('.gn-radius-field-wrapper').addClass('d-none');
                location_form.find('.gn-radius-field-wrapper input.gn-required-field').removeClass('gn-required-field').addClass('gn-not-required-field');
            } else {
                max_radius.removeClass('d-none');
                location_form.find('.gn-map-field-wrapper').removeClass('col-md-12').addClass('col-md-6');
                location_form.find('.gn-radius-field-wrapper').removeClass('d-none');
                location_form.find('.gn-radius-field-wrapper input.gn-not-required-field').removeClass('gn-not-required-field').addClass('gn-required-field');
            }
        });

        //Location Edit
        $(document).on('gigneo_modal_before_open', function (e, _this, modal_id) {
            let selector = $('#' + modal_id);
            let fields = _this.data('gn-fields');

            if (selector.hasClass('gn-service-location-modal')) {
                let map = selector.find('.gn-map');
                if (fields !== undefined) {
                    if (typeof fields === 'object') {
                        $.each(fields, function (key, value) {
                            let field = selector.find(`[name="${key}"]`);
                            if (map.length && ('lat' === key || 'lng' === key)) {
                                selector.find('.gn-map').attr(`data-${key}`, value);
                            }
                            if (field.length) {
                                if ('location' === key) {
                                    field.val(JSON.stringify(value));
                                } else {
                                    field.val(value).trigger("change");
                                }
                            }
                        });
                        window.GigneoSelect2.init();
                        if (map.length) {
                            let mapID = map.attr('id');
                            window.GigneoGoogleMap?.init({
                                selector: `#${mapID}`
                            });
                        }
                    } else {
                        selector.find('form#gn-save-service-location-form')[0].reset();
                        selector.find('.gn-form-fields input,.gn-form-fields textarea,.gn-form-fields select').val('').prop('checked', false).prop('selected', false);
                        selector.find('input[name="location_id"]').val('');
                        selector.find('#gn-country-state').trigger('change');
                    }
                }
            }

        });

        //Country State & Cities for location
        $(document).on('change', '#gn-save-service-location-form select[name="country_state"]', function () {
            let _this = $(this);
            let country_state = _this.val();
            let cities_selector = $('#gn-save-service-location-form select[name="city"]');

            // Reset dropdown
            cities_selector.empty();

            // Add default "None" option first
            cities_selector.append(
                $('<option>', {
                    value: 'none',
                    text: GigneoCommon.none ?? 'None'
                })
            );

            if (country_state && GigneoDashboard.cities[country_state] !== undefined) {
                let cities = GigneoDashboard.cities[country_state];

                Object.entries(cities).forEach(function ([value, label]) {
                    cities_selector.append(
                        $('<option>', {
                            value: value,
                            text: label
                        })
                    );
                });
            }

            // Refresh Select2
            cities_selector.trigger('change.select2');
        });

        //Location Save
        $(document).on('submit', '#gn-save-service-location-form', function (e) {
            e.preventDefault();

            let _this = $(this);
            let proceed = true;
            let form_data = new FormData(this);
            let submit_btn = _this.find('button[type="submit"]');
            let delivery_type = $('#gn-service-form-details .gn-onsite-delivery-type input[name="delivery_type"]:checked').val();

            proceed = window.GigneoRequiredFormFields.init(_this, proceed);

            if (proceed) {

                let url = new URL(window.location.href);
                let params = new URLSearchParams(url.search);

                let id = params.get('p_id');

                form_data.append('action', 'gigneo_save_service_location');
                form_data.append('security', GigneoCommon.security);
                form_data.append('id', id);
                form_data.append('delivery_type', delivery_type);

                submit_btn.addClass('gn-loading');

                $.ajax({
                    url: GigneoCommon.ajax_url,
                    method: 'POST',
                    data: form_data,
                    contentType: false,
                    processData: false,
                    success: function (response) {
                        submit_btn.removeClass('gn-loading');

                        if (response.success) {

                            if (response.data.locations && '' !== response.data.locations) {
                                let location_html = $(response.data.locations).html();
                                $('#gn-edit-service-locations').html(location_html);
                                window.GigneoSelect2.init();
                                window.GigneoGoogleMap?.init();
                            }

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

                            if (response.data.message) {
                                GigneoAlert.toast({
                                    icon: 'success',
                                    title: GigneoCommon.success,
                                    text: response.data.message
                                });
                            }

                        }
                    },
                    error: function (xhr, status, error) {
                        submit_btn.removeClass('gn-loading');
                        let error_message = xhr?.responseJSON?.data.message || GigneoCommon.went_wrong;
                        GigneoAlert.toast({
                            icon: 'error',
                            title: GigneoCommon.error,
                            text: error_message
                        });
                    }
                });
            }

        });

        //Remove Location
        $(document).on('click', '.gn-remove-location', function (e) {
            e.preventDefault();
            let _this = $(this);
            let id = _this.data('gn-id');
            let location_id = _this.data('gn-location-id');

            GigneoAlert.confirm({
                icon: "error",
                text: GigneoCommon.delete_confirmation_desc,
                confirmButtonText: GigneoCommon.delete,
                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: GigneoCommon.ajax_url,
                            method: 'POST',
                            data: {
                                action: 'gigneo_remove_service_location',
                                security: GigneoCommon.security,
                                id: id,
                                location_id: location_id
                            },
                            success: function (response) {
                                confirmBtn.classList.remove('gn-loading');
                                confirmBtn.disabled = false;

                                if (response.success) {

                                    if (response.data.locations && '' !== response.data.locations) {
                                        let location_html = $(response.data.locations).html();
                                        $('#gn-edit-service-locations').html(location_html);
                                        window.GigneoSelect2.init();
                                        window.GigneoGoogleMap?.init();
                                    }

                                    if (response.data.message) {
                                        GigneoAlert.toast({
                                            icon: 'success',
                                            title: GigneoCommon.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 || GigneoCommon.went_wrong;
                                GigneoAlert.toast({
                                    icon: 'error',
                                    title: GigneoCommon.error,
                                    text: error_message
                                });
                                return Promise.resolve();
                            }
                        });
                    });
                }
            });

        });

        //Add Faq
        $(document).on('click', '.gn-add-faq', function (e) {
            e.preventDefault();

            let _this = $(this);
            let wrapper = $('#gn-service-edit-details');
            let faq_count = $(document).find('.gn-faqs .gn-faq').length;

            let faq_template = wp.template('gn-faq');
            let faq_html = faq_template({ index: faq_count });

            wrapper.find('.gn-faqs').append(faq_html);

        });

        //Remove Faq
        $(document).on('click', '.gn-remove-faq', function (e) {
            e.preventDefault();

            let _this = $(this);
            let faq_id = _this.data('gn-remove-faq-id') ?? _this.data('gn-faq-id');
            if (typeof faq_id !== 'undefined' && faq_id !== '' && $(document).find(`#gn-faq-${faq_id}`).length > 0) {
                $(document).find(`#gn-faq-${faq_id}`).remove();
            } else {
                _this.closest('.gn-faq').remove();
            }
        });

        //Gallery Images
        $('.gn-service-media-gallery > .gn-service-media').each(function (index) {

            $(`.gn-service-media-gallery .gn-service-media-${index} .gn-service-media-upload-toggle`).GigneoUploader({
                previewSelector: `.gn-service-media-gallery .gn-service-media-${index} .gn-service-image > img`,
                inputSelector: `.gn-service-media-gallery #gn-service-media-input-${index}`,
                removeSelector: `.gn-service-media-gallery .gn-service-media-${index} .gn-service-media-remove`,
                width: 1200,
                height: 600,
                crop: true,
                previewMode: 'attribute',
                previewAttribute: 'src',
                allowedExtensions: GigneoDashboard.image_extensions || ['jpg', 'jpeg', 'png'],
                maxFileSize: (GigneoDashboard.image_max_size || 1) * 1024 * 1024,
                placeholderUrl: '',
                previewCallback: function (preview, attachment) {
                    let parent_selector = $(preview).parents('.gn-service-media');
                    if (attachment.url) {
                        let currentId = String(attachment.id || attachment.attachment_id);
                        let isDuplicate = false;

                        $('.gn-service-media-gallery input[name="gigneo_pm_gallery[]"]').not(`.gn-service-media-gallery #gn-service-media-input-${index}`).each(function () {
                            if ($(this).val() && String($(this).val()) === currentId) {
                                isDuplicate = true;
                                return false;
                            }
                        });

                        if (isDuplicate) {
                            GigneoAlert.toast({
                                icon: 'error',
                                title: GigneoCommon.error,
                                text: GigneoCommon.duplicate_image_notice || 'Duplicate image selected.'
                            });
                            setTimeout(function () {
                                $(`.gn-service-media-gallery .gn-service-media-${index} .gn-service-media-remove`).trigger('click');
                            }, 50);
                            return;
                        }

                        parent_selector.removeClass('gn-service-media-placeholder');
                    } else {
                        parent_selector.addClass('gn-service-media-placeholder');
                        $(document).find('.gn-service-media-gallery .gn-service-media-placeholder').appendTo('.gn-service-media-gallery');
                    }
                }
            });

        });

        //Change Video Type
        $(document).on('change', '#gn-service-edit-media input[name="gigneo_pm_video_type"]', function (e) {

            let value = $('#gn-service-edit-media input[name="gigneo_pm_video_type"]:checked').val();

            if ('link' === value) {
                $('.gn-service-media-video').addClass('d-none');
                $('.gn-service-video-link-wrapper').removeClass('d-none');
            } else {
                $('.gn-service-media-video').removeClass('d-none');
                $('.gn-service-video-link-wrapper').addClass('d-none');
            }
        });

        //Video
        $(`.gn-service-media-video .gn-service-media-upload-toggle`).GigneoUploader({
            previewSelector: '.gn-service-media-video video > source',
            inputSelector: '.gn-service-media-video #gn-service-media-video-input',
            removeSelector: '.gn-service-media-video .gn-service-media-remove',
            crop: false,
            previewMode: 'attribute',
            previewAttribute: 'src',
            allowedExtensions: GigneoDashboard.video_extensions || ['mp4', 'avi', 'mov'],
            maxFileSize: GigneoDashboard.video_max_size * 1024 * 1024 || 10485760,
            placeholderUrl: '',
            previewCallback: function (preview, attachment) {
                let parent_selector = $(preview).parents('.gn-service-media');
                if (attachment.url) {
                    let video = $(preview).closest('video');
                    $(preview).attr('type', attachment?.mime);
                    parent_selector.removeClass('gn-service-media-placeholder');
                    video[0].load();
                } else {
                    parent_selector.addClass('gn-service-media-placeholder');
                }
            }
        });

        //Documents Images
        $('.gn-service-media-documents > .gn-service-media').each(function (index) {

            $(`.gn-service-media-documents .gn-service-media-${index} .gn-service-media-upload-toggle`).GigneoUploader({
                previewSelector: `.gn-service-media-documents .gn-service-media-${index}`,
                inputSelector: `.gn-service-media-documents #gn-service-media-input-${index}`,
                removeSelector: `.gn-service-media-documents .gn-service-media-${index} .gn-service-media-remove`,
                crop: false,
                previewMode: 'custom',
                allowedExtensions: GigneoDashboard.document_extensions || ['pdf', 'doc', 'docx', 'txt'],
                maxFileSize: GigneoDashboard.document_max_size * 1024 * 1024 || 5242880,
                placeholderUrl: '',
                previewCallback: function (preview, attachment) {
                    if (attachment.url) {
                        let currentId = String(attachment.id || attachment.attachment_id);
                        let isDuplicate = false;

                        $('.gn-service-media-documents input[name="gigneo_pm_documents[]"]').not(`.gn-service-media-documents #gn-service-media-input-${index}`).each(function () {
                            if ($(this).val() && String($(this).val()) === currentId) {
                                isDuplicate = true;
                                return false;
                            }
                        });

                        if (isDuplicate) {
                            GigneoAlert.toast({
                                icon: 'error',
                                title: GigneoCommon.error,
                                text: GigneoCommon.duplicate_document_notice || 'Duplicate document selected.'
                            });
                            setTimeout(function () {
                                $(`.gn-service-media-documents .gn-service-media-${index} .gn-service-media-remove`).trigger('click');
                            }, 50);
                            return;
                        }

                        $(preview).removeClass('gn-service-media-placeholder');
                        $(preview).find('.gn-name').html(attachment.filename);
                    } else {
                        $(preview).addClass('gn-service-media-placeholder');
                        $(document).find('.gn-service-media-documents .gn-service-media-placeholder').appendTo('.gn-service-media-documents');
                        $(preview).find('.gn-name').empty();
                    }
                }
            });

        });

        let lastRequirementRadio = null;

        // Click requirement radio check
        $(document).on('click', '.gn-intake-form-type input[name="requirement_type"]', function () {

            let _this = $(this);

            if (lastRequirementRadio && lastRequirementRadio[0] === this) {
                _this.prop('checked', false);
                lastRequirementRadio = null;
                _this.trigger('change');
                return;
            }

            lastRequirementRadio = _this;
        });

        // Requirement Type Change
        $(document).on('change', '.gn-intake-form-type input[name="requirement_type"]', function () {

            const _this = $(this);
            const selector = $('#gn-requirement-questions');

            // Normal checked state
            if (_this.is(':checked') && (_this.val() === 'pre' || _this.val() === 'post')) {
                selector.removeClass('d-none');
                selector.find('.gn-not-required-field').removeClass('gn-not-required-field').addClass('gn-required-field');
            } else {
                selector.addClass('d-none');
                selector.find('.gn-required-field').removeClass('gn-required-field').addClass('gn-not-required-field');
            }
        });

        //Add Requirement question
        $(document).on('click', '.gn-add-requirement', function (e) {
            e.preventDefault();

            let _this = $(this);
            let wrapper = $('#gn-service-edit-requirements');
            let req_count = $(document).find('.gn-requirements .gn-requirement').length;

            let req_template = wp.template('gn-requirement');
            let req_html = req_template({ index: req_count });

            wrapper.find('.gn-requirements').append(req_html);
            GigneoSelect2.init();

        });

        //Remove Requirement
        $(document).on('click', '.gn-remove-requirement', function (e) {
            e.preventDefault();

            let _this = $(this);
            let req_id = _this.data('gn-requirement-id');
            if (req_id !== '') {
                $(document).find(`#gn-requirement-${req_id}`).remove();
            }
        });

        //Change Requirement Answer Type
        $(document).on('change', '.gn-requirement-answer-type', function (e) {
            e.preventDefault();

            let _this = $(this);
            let val = _this.val();
            let selector = _this.parents('.gn-form-field ').find('.gn-requirement-choices');

            if ('choice' === val) {
                selector.removeClass('d-none');
                selector.find('.gn-requirement-choice input').removeClass('gn-not-required-field').addClass('gn-required-field');
            } else {
                selector.addClass('d-none');
                selector.find('.gn-requirement-choice input').removeClass('gn-required-field').addClass('gn-not-required-field');
            }

        });

        //Add Requirement Choice
        $(document).on('click', '.gn-add-requirement-choice', function (e) {
            e.preventDefault();

            let _this = $(this);
            let req_field_inex = $(_this).data('gn-field-id');
            let req_field = $(`#gn-requirement-${req_field_inex}`);

            if (!req_field.length) {
                return
            }

            let index = req_field.find('.gn-requirement-choice').length;

            let req_choice_template = wp.template('gn-requirement-choice');
            let req_choice_html = req_choice_template({ field: req_field_inex, index: index });

            req_field.find('.gn-requirement-choice-actions').before(req_choice_html);

        });

        //Remove Requirement Choice
        $(document).on('click', '.gn-remove-requirement-choice', function (e) {
            e.preventDefault();

            let _this = $(this);
            let req_choice_id = _this.data('gn-requirement-choice-id');
            if (req_choice_id !== '') {
                $(document).find(`#${req_choice_id}`).remove();
            }
        });

        //Publish service form
        $(document).on('submit', '#gn-service-publish-form', function (e) {
            e.preventDefault();

            let _this = $(this);
            let proceed = true;
            let form_data = new FormData(this);
            let submit_btn = _this.find('button[type="submit"]');
            let redirect = submit_btn.data('gn-redirect-url')
            let url = new URL(window.location.href);
            let params = new URLSearchParams(url.search);
            let id = params.get('p_id');
            proceed = window.GigneoRequiredFormFields.init(_this, proceed);

            if (proceed) {

                form_data.append('action', 'gigneo_publish_service');
                form_data.append('security', GigneoCommon.security);
                form_data.append('id', id);

                submit_btn.addClass('gn-loading');

                $.ajax({
                    url: GigneoCommon.ajax_url,
                    method: 'POST',
                    data: form_data,
                    contentType: false,
                    processData: false,
                    success: function (response) {

                        window.location.href = redirect;

                        submit_btn.removeClass('gn-loading');

                        if (response.success) {

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

                            if (response.data.message) {
                                GigneoAlert.toast({
                                    icon: 'success',
                                    title: GigneoCommon.success,
                                    text: response.data.message
                                });
                            }

                        }
                    },
                    error: function (xhr, status, error) {
                        submit_btn.removeClass('gn-loading');
                        let error_message = xhr?.responseJSON?.data.message || GigneoCommon.went_wrong;
                        GigneoAlert.toast({
                            icon: 'error',
                            title: GigneoCommon.error,
                            text: error_message
                        });
                    }
                });
            }

        });
    }

})(jQuery);