(function ($) {
    "use strict";

    /* ===================================
        Order Detail
    ====================================== */

    //Delivery Date/Time
    jQuery(document).ready(function () {
        
        let countdown = jQuery('#gn-order-delivery-countdown');
        let deliveryStr = countdown.data('gn-delivery');
        let nowStr = countdown.data('gn-now');

        if (countdown.length && deliveryStr) {

            var deliveryTime = new Date(deliveryStr.replace(' ', 'T'));
            var currentTime = new Date(nowStr.replace(' ', 'T'));

            var interval = setInterval(function () {
                var diff = deliveryTime - currentTime;

                if (isNaN(diff) || diff <= 0) {
                    clearInterval(interval);
                    jQuery('#gn-days, #gn-hours, #gn-minutes, #gn-seconds').text('00');
                    countdown.removeClass('gn-status-pending').addClass('gn-status-delivered');
                    return;
                }

                var days = Math.floor(diff / (1000 * 60 * 60 * 24));
                var hours = Math.floor((diff / (1000 * 60 * 60)) % 24);
                var minutes = Math.floor((diff / (1000 * 60)) % 60);
                var seconds = Math.floor((diff / 1000) % 60);

                // Replace NaN with 0 before formatting
                days = isNaN(days) ? 0 : days;
                hours = isNaN(hours) ? 0 : hours;
                minutes = isNaN(minutes) ? 0 : minutes;
                seconds = isNaN(seconds) ? 0 : seconds;

                jQuery('#gn-days').text(('0' + days).slice(-2));
                jQuery('#gn-hours').text(('0' + hours).slice(-2));
                jQuery('#gn-minutes').text(('0' + minutes).slice(-2));
                jQuery('#gn-seconds').text(('0' + seconds).slice(-2));

                // increment current time by 1 second
                currentTime = new Date(currentTime.getTime() + 1000);
            }, 1000);
        }
        //Modal Toggle
        $(document).on('click', '#gn-add-order-note', function (e) {
            let _this = $(this),
                modal_id = 'gn-order-note-modal',
                modal = $('#' + modal_id);

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

                // Trigger your custom events
                $(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]);
                $("#gn-order-note-modal #gn-note-id").val('');

                let editor = tinymce.get('gn-order-note');
                if (editor) {
                    editor.setContent('');
                }
            }
        });
    });


    // Intake Attachments
    const intakeFormAttachments = {};

    let requirement_attachments_selector = $('.gn-order-requirement-form .gn-plupload-container');

    if (requirement_attachments_selector.length) {
        //Initialize PlUploader
        requirement_attachments_selector.each((i, container) => {
            let index = $(container).data('gn-index');
            initIntakeFormPluploadInit(index);
        });
    }

    //Intake Form Plupload Init
    function initIntakeFormPluploadInit(index) {
        if (typeof plupload !== 'object') {
            return;
        }

        // Unique IDs for this uploader
        const containerId = `gn-intake-form-attachment-container-${index}`;
        const browseButtonId = `gn-intake-form-attachment-uploader-${index}`;
        const dropAreaId = `gn-intake-form-attachment-drop-area-${index}`;
        const attachmentListId = `gn-intake-form-attachment-list-${index}`;

        // Initialize file array for this uploader
        intakeFormAttachments[index] = { files: [], uploader: null };

        // Get settings from GigneoDashboard or defaults
        const extensions = GigneoCommon.intake_form_extensions || ['jpg', 'jpeg', 'png', 'doc'];
        const maxFiles = parseInt(GigneoCommon.intake_form_max_files) || 3;
        const maxSize = parseInt(GigneoCommon.intake_form_max_size) || 1;

        // Initialize Plupload
        let uploader = new plupload.Uploader({
            browse_button: browseButtonId,
            container: containerId,
            drop_element: dropAreaId,
            filters: {
                mime_types: [{ title: 'Files', extensions: extensions.join(',') }],
                // max_file_count: maxFiles,
                // max_file_size: `${maxSize}mb`
            }
        });

        uploader.init();
        intakeFormAttachments[index].uploader = uploader;

        // Handle FilesAdded
        uploader.bind('FilesAdded', (up, files) => {
            const $attachmentList = $(`#${attachmentListId}`);
            // Check total file count
            if (intakeFormAttachments[index].files.length + files.length > maxFiles) {
                GigneoAlert.toast({
                    icon: 'error',
                    title: GigneoCommon.error || 'Error',
                    text: GigneoDashboard.intake_form_max_files_notice || `Maximum ${maxFiles} files allowed.`
                });
                files.forEach(f => up.removeFile(f));
                return;
            }
  uploader.bind('Error', (up, err) => {
            let errorText = err.message || 'An error occurred during file upload.';
            if (err.code === plupload.FILE_EXTENSION_ERROR) {
                errorText = GigneoDashboard.invalid_extension_notice || 'Invalid file type.';
            } else if (err.code === plupload.FILE_SIZE_ERROR) {
                errorText = GigneoDashboard.intake_form_max_size_notice || `File size exceeds ${maxSize}MB.`;
            }
            GigneoAlert.toast({
                icon: 'error',
                title: GigneoCommon.error || 'Error',
                text: errorText
            });
        });
        
            // Validate each file
            files.forEach(file => {
                const ext = file.name.split('.').pop().toLowerCase();

                // Check extension
                if (!extensions.includes(ext)) {
                    GigneoAlert.toast({
                        icon: 'error',
                        title: GigneoCommon.error || 'Error',
                        text: GigneoDashboard.invalid_extension_notice || 'Invalid file type.'
                    });
                    up.removeFile(file);
                    return;
                }

                // Check file size
                if (file.size > maxSize * 1024 * 1024) {
                    GigneoAlert.toast({
                        icon: 'error',
                        title: GigneoCommon.error || 'Error',
                        text: GigneoDashboard.intake_form_max_size_notice || `File size exceeds ${maxSize}MB.`
                    });
                    up.removeFile(file);
                    return;
                }

                // Add to file list and UI
                intakeFormAttachments[index].files.push(file);
                $attachmentList.append(
                    `<div id="${file.id}" class="gn-attachment-item">${file.name}<button type="button" class="gn-attachment-remove" data-file-id="${file.id}" data-uploader-index="${index}"><i class="hi hi-trash" aria-hidden="true"></i></button></div>`
                );
            });

            up.refresh();
        });

        $(document).on('click', '.gn-order-requirement-form .gn-attachment-remove', function (e) {
            const $this = $(this);
            const fileId = $this.data('file-id');
            const uploaderIndex = $this.data('uploader-index');

            const uploader = intakeFormAttachments[uploaderIndex]?.uploader;
            if (uploader) {
                const file = uploader.getFile(fileId);
                if (file) {
                    uploader.removeFile(file);
                    intakeFormAttachments[uploaderIndex].files = intakeFormAttachments[uploaderIndex].files.filter(f => f.id !== fileId);
                    $this.closest(`#${fileId}`).fadeOut(100, function () {
                        $(this).remove();
                    });
                }
            }
        });

    }

    //Intake Form Submit
    $(document).on('submit', '#gn-order-requirement-form', function (e) {
        e.preventDefault();
        let _this = $(this);
        let proceed = true;

        let form_data = new FormData(_this[0]);

        // validate before proceeding
        proceed = window.GigneoRequiredFormFields.init(_this, proceed);

        requirement_attachments_selector.each((i, container) => {
            let index = $(container).data('gn-index');
            let required = $(container).data('gn-required');
            let attachment_files = intakeFormAttachments[index].files || [];

            if (required && attachment_files.length === 0) {
                GigneoAlert.toast({
                    icon: 'error',
                    title: GigneoCommon.error,
                    text: GigneoCommon.required_fields
                });
                proceed = false;
            }
        });

        if (!proceed) return;

        let submit_btn = _this.find('#gn-requirements-submit');

        form_data.append('action', 'gigneo_service_order_requirements_submit');
        form_data.append('security', GigneoCommon.security);

        // Append files from each uploader
        if (intakeFormAttachments) {
            Object.keys(intakeFormAttachments).forEach(index => {
                intakeFormAttachments[index].files.forEach(file => {
                    form_data.append(`intake_form_attachments[${index}][]`, file.getNative(), file.name);
                });
            });
        }

        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.data.message) {
                    GigneoAlert.toast({
                        icon: 'success',
                        title: GigneoCommon.success,
                        text: response.data.message
                    });
                }

                location.reload();
            },
            error: function (response) {
                submit_btn.removeClass('gn-loading');
                GigneoAlert.toast({
                    icon: 'error',
                    title: GigneoCommon.error,
                    text: response.responseJSON && response.responseJSON.data && response.responseJSON.data.message ? response.responseJSON.data.message : ''
                });
            },
        });
    });

    // Extend Delivery Date Request
    $(document).on('submit', '#gn-extend-delivery-form', function (e) {
        e.preventDefault();

        let _this = $(this);
        let proceed = true;
        let form_data = new FormData(_this[0]);
        form_data.append('action', 'gigneo_service_order_extend_delivery_request');
        form_data.append('security', GigneoCommon.security);
        let submit_btn = _this.find('button[type="submit"]');

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

        if (proceed) {
            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) {

                        location.reload();

                        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
                    });
                }
            });
        }

    });

    //Extend Delivery Request Respond
    $(document).on('click', '#gn-order-extend-delivery-date-approve,#gn-order-extend-delivery-date-decline', function (e) {
        e.preventDefault();
        let _this = $(this);
        let btn_id = _this.attr('id');
        let order_id = _this.data('gn-order-id');
        let type = 'gn-order-extend-delivery-date-approve' === btn_id ? 'approve' : 'decline';

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

        GigneoAlert.confirm({
            icon: "decline" === type ? "error" : "warning",
            text: "decline" === type ? GigneoDashboard.decline_extend_date_request_confirmation_desc : GigneoDashboard.approve_extend_date_request_confirmation_desc,
            confirmButtonText: "decline" === type ? GigneoCommon.decline : GigneoCommon.approve,
            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_service_order_extend_delivery_date_respond',
                            order_id: order_id,
                            type: type,
                            security: GigneoCommon.security
                        },
                        success: function (response) {
                            confirmBtn.classList.remove('gn-loading');
                            confirmBtn.disabled = false;

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

                            location.reload();
                            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();
                        }
                    });
                });
            }
        });

    });

    //Service Order Attachments
    const service_order_attachments_plupload = GigneoPlupload.init({
        browseButtonId: 'gn-service-order-attachment-uploader',
        containerId: 'gn-service-order-attachment-container',
        dropElementId: 'gn-service-order-attachment-drop-area',
        attachmentListId: 'gn-service-order-attachment-list',
        allowedExtensions: GigneoDashboard.service_order_extensions || ['jpg,jpeg,png,doc'],
        maxFiles: GigneoDashboard.service_order_max_files || '3',
        maxSizeMb: GigneoDashboard.service_order_max_size || '1',
        errorMessages: {
            maxFiles: GigneoDashboard.service_order_max_files_notice,
            invalidExtension: GigneoDashboard.service_order_extension_notice,
            maxSize: GigneoDashboard.service_order_max_size_notice
        }
    });

    //Attachment Upload Cancel
    $(document).on('click', '#gn-service-order-attachments-cancel', function (e) {
        let { files, uploader } = service_order_attachments_plupload;
        if (uploader) {
            uploader.splice(0, uploader.files.length);
            files.length = 0;
            $('#gn-service-order-attachment-list').empty();
            uploader.refresh();
        }
    });

    //Attachment Upload
    $(document).on('click', '#gn-service-order-attachments-upload', function (e) {
        e.preventDefault();
        let _this = $(this);
        let _id = _this.data('gn-order-id');
        let { files, uploader } = service_order_attachments_plupload;

        if (!files || !_id) {
            GigneoAlert.toast({
                icon: 'error',
                title: GigneoCommon.error,
                text: GigneoCommon.required_fields
            });
        }

        let form_data = new FormData();
        form_data.append('action', 'gigneo_service_order_attachments_upload');
        form_data.append('security', GigneoCommon.security);
        form_data.append('order_id', _id);

        if (uploader && files.length > 0) {
            files.forEach(function (file, i) {
                form_data.append('attachments[]', file.getNative(), file.name);
            });
        }

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

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

                location.reload();

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

            },
            error: function (response) {
                _this.removeClass('gn-loading').attr('disabled', false);
                GigneoAlert.toast({
                    icon: 'error',
                    title: GigneoCommon.error,
                    text: response.responseJSON && response.responseJSON.data && response.responseJSON.data.message ? response.responseJSON.data.message : ''
                });
            },
        });

    });

    //Submit Order
    $(document).on('submit', '#gn-service-order-deliver-form', function (e) {
        e.preventDefault();
        let _this = $(this);
        let _id = _this.find('input[name="order_id"]').val();
        let type = _this.find('select[name="order_delivery_type"]').val();
        let description = _this.find('textarea[name="order_delivery_description"]').val();
        let submit_btn = _this.find('button[type="submit"]');
        let proceed = true;
        let { files, uploader } = service_order_delivery_plupload;

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

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

        if (!files || !_id) {
            GigneoAlert.toast({
                icon: 'error',
                title: GigneoCommon.error,
                text: GigneoCommon.required_fields
            });
            proceed = false;
        }

        if (!proceed) {
            return;
        }

        let form_data = new FormData();
        form_data.append('action', 'gigneo_service_order_deliver');
        form_data.append('security', GigneoCommon.security);
        form_data.append('order_id', _id);
        form_data.append('type', type);
        form_data.append('description', description);

        if (uploader && files.length > 0) {
            files.forEach(function (file, i) {
                form_data.append('attachments[]', file.getNative(), file.name);
            });
        }

        submit_btn.addClass('gn-loading').attr('disabled', true);

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

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

                location.reload();

            },
            error: function (response) {
                submit_btn.removeClass('gn-loading').attr('disabled', false);
                GigneoAlert.toast({
                    icon: 'error',
                    title: GigneoCommon.error,
                    text: response.responseJSON && response.responseJSON.data && response.responseJSON.data.message ? response.responseJSON.data.message : ''
                });
            },
        });

    });

    //Order Revision
    $(document).on('submit', '#gn-service-order-revision-form', function (e) {
        e.preventDefault();
        let _this = $(this);
        let _id = _this.find('input[name="order_id"]').val();
        let description = _this.find('textarea[name="order_revision_description"]').val();
        let submit_btn = _this.find('button[type="submit"]');
        let { files, uploader } = service_order_attachments_plupload;
        let proceed = true;

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

        if (!proceed) {
            return false;
        }

        let form_data = new FormData();
        form_data.append('action', 'gigneo_service_order_revision');
        form_data.append('security', GigneoCommon.security);
        form_data.append('order_id', _id);
        form_data.append('description', description);

        if (uploader && files.length > 0) {
            files.forEach(function (file, i) {
                form_data.append('attachments[]', file.getNative(), file.name);
            });
        }

        submit_btn.addClass('gn-loading').attr('disabled', true);

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

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

                location.reload();

            },
            error: function (response) {
                submit_btn.removeClass('gn-loading').attr('disabled', false);
                GigneoAlert.toast({
                    icon: 'error',
                    title: GigneoCommon.error,
                    text: response.responseJSON && response.responseJSON.data && response.responseJSON.data.message ? response.responseJSON.data.message : ''
                });
            },
        });

    })

    //Approver Order Delivery
    $(document).on('click', '#gn-service-order-delivery-approve', function (e) {
        e.preventDefault();
        let _this = $(this);
        let order_id = _this.data('gn-order-id');

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

        GigneoAlert.confirm({
            icon: "warning",
            text: GigneoDashboard.approve_delivery_confirmation_desc,
            confirmButtonText: GigneoCommon.approve,
            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_service_order_delivery_approve',
                            id: order_id,
                            security: GigneoCommon.security
                        },
                        success: function (response) {
                            confirmBtn.classList.remove('gn-loading');
                            confirmBtn.disabled = false;

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

                            location.reload();
                            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();
                        }
                    });
                });
            }
        });

    });

    //Review Stars
    $(document).on('click', '.gn-order-activity .gn-review-stars > i', function () {
        let index = $(this).index();
        let container = $(this).parent();
        let input = container.parent().find('.gn-review-stars-input');

        container.children("i").each(function (i) {
            $(this).toggleClass("gn-active", i <= index);
        });

        $(input).val(index + 1);
    });

    //Submit Feedback
    $(document).on('submit', '.gn-service-order-detail #gn-freelancer-review-form, .gn-service-order-detail #gn-employer-review-form', function (e) {
        e.preventDefault();

        let _this = $(this);
        let proceed = true;
        let form_data = new FormData(_this[0]);
        form_data.append('action', 'gigneo_service_order_review');
        form_data.append('security', GigneoCommon.security);
        let submit_btn = _this.find('button[type="submit"]');

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

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

        if (!proceed) {
            return false;
        }

        submit_btn.addClass('gn-loading');

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

                if (response.success) {
                    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
                });
            }
        });
    });

    //Complete Order
    $(document).on('click', '#gn-service-order-complete', function (e) {
        e.preventDefault();
        let _this = $(this);
        let order_id = _this.data('gn-order-id');

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

        GigneoAlert.confirm({
            icon: "warning",
            text: GigneoCommon.complete_confirmation_desc,
            confirmButtonText: GigneoCommon.complete,
            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_service_order_complete',
                            id: order_id,
                            security: GigneoCommon.security
                        },
                        success: function (response) {
                            confirmBtn.classList.remove('gn-loading');
                            confirmBtn.disabled = false;

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

                            location.reload();
                            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();
                        }
                    });
                });
            }
        });

    });

    //Cancel Order
    $(document).on('click', '#gn-service-order-cancel-btn', function (e) {
        e.preventDefault();
        let _this = $(this);
        let order_id = _this.data('gn-order-id');

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

        GigneoAlert.confirm({
            icon: "error",
            text: GigneoCommon.cancel_confirmation_desc,
            confirmButtonText: GigneoCommon.cancel,
            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_service_order_cancel',
                            order_id: order_id,
                            security: GigneoCommon.security
                        },
                        success: function (response) {
                            confirmBtn.classList.remove('gn-loading');
                            confirmBtn.disabled = false;

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

                            location.reload();
                            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();
                        }
                    });
                });
            }
        });

    });

    //Cancel Order Request
    $(document).on('submit', '#gn-service-order-cancel-request-form', function (e) {
        e.preventDefault();

        let _this = $(this);
        let proceed = true;
        let form_data = new FormData(_this[0]);
        form_data.append('action', 'gigneo_service_order_cancel');
        form_data.append('security', GigneoCommon.security);
        let submit_btn = _this.find('button[type="submit"]');

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

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

        if (!proceed) {
            return false;
        }

        submit_btn.addClass('gn-loading');

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

                if (response.success) {
                    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
                });
            }
        });
    });

    //Cancel Request Respond
    $(document).on('click', '#gn-order-cancel-approve,#gn-order-cancel-decline', function (e) {
        e.preventDefault();
        let _this = $(this);
        let btn_id = _this.attr('id');
        let order_id = _this.data('gn-order-id');
        let type = 'gn-order-cancel-approve' === btn_id ? 'approve' : 'decline';

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

        GigneoAlert.confirm({
            icon: "decline" === type ? "error" : "warning",
            text: "decline" === type ? GigneoDashboard.decline_cancel_request_confirmation_desc : GigneoDashboard.approve_cancel_request_confirmation_desc,
            confirmButtonText: "decline" === type ? GigneoCommon.decline : GigneoCommon.approve,
            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_service_order_cancel_respond',
                            order_id: order_id,
                            type: type,
                            security: GigneoCommon.security
                        },
                        success: function (response) {
                            confirmBtn.classList.remove('gn-loading');
                            confirmBtn.disabled = false;

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

                            location.reload();
                            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();
                        }
                    });
                });
            }
        });

    });



    //Attachments Filter
    $(document).on('click', '#gn-order-attachments .gn-attachment-filters > li', function (e) {
        e.preventDefault();

        let _this = $(this);
        let filter = _this.data('gn-filter');
        let wrapper = $('#gn-order-attachments .gn-attachment-list');

        if ('all' === filter) {
            wrapper.find('li.gn-attachment').show();
        } else {
            wrapper.find('li.gn-attachment').hide();
            wrapper.find(`li.gn-attachment.gn-${filter}`).show();
        }

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

    /* ===================================
        Job Order Handlers
    ====================================== */

    //Job Order Attachments
    const job_order_attachments_plupload = GigneoPlupload.init({
        browseButtonId: 'gn-job-order-attachment-uploader',
        containerId: 'gn-job-order-attachment-container',
        dropElementId: 'gn-job-order-attachment-drop-area',
        attachmentListId: 'gn-job-order-attachment-list',
        allowedExtensions: GigneoDashboard.job_order_extensions || ['jpg,jpeg,png,doc'],
        maxFiles: GigneoDashboard.job_order_max_files || '3',
        maxSizeMb: GigneoDashboard.job_order_max_size || '1',
        errorMessages: {
            maxFiles: GigneoDashboard.job_order_max_files_notice,
            invalidExtension: GigneoDashboard.job_order_extension_notice,
            maxSize: GigneoDashboard.job_order_max_size_notice
        }
    });

    //Job Order Attachment Upload Cancel
    $(document).on('click', '#gn-job-order-attachments-cancel', function (e) {
        let { files, uploader } = job_order_attachments_plupload;
        if (uploader) {
            uploader.splice(0, uploader.files.length);
            files.length = 0;
            $('#gn-job-order-attachment-list').empty();
            uploader.refresh();
        }
    });

    //Job Order Attachment Upload
    $(document).on('click', '#gn-job-order-attachments-upload', function (e) {
        e.preventDefault();
        let _this = $(this);
        let _id = _this.data('gn-order-id');
        let { files, uploader } = job_order_attachments_plupload;

        if (!files || !_id) {
            GigneoAlert.toast({
                icon: 'error',
                title: GigneoCommon.error,
                text: GigneoCommon.required_fields
            });
        }

        let form_data = new FormData();
        form_data.append('action', 'gigneo_job_order_attachments_upload');
        form_data.append('security', GigneoCommon.security);
        form_data.append('order_id', _id);

        if (uploader && files.length > 0) {
            files.forEach(function (file, i) {
                form_data.append('attachments[]', file.getNative(), file.name);
            });
        }

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

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

                location.reload();

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

            },
            error: function (response) {
                _this.removeClass('gn-loading').attr('disabled', false);
                GigneoAlert.toast({
                    icon: 'error',
                    title: GigneoCommon.error,
                    text: response.responseJSON && response.responseJSON.data && response.responseJSON.data.message ? response.responseJSON.data.message : ''
                });
            },
        });

    });

    //Submit Job Order Deliver
    $(document).on('submit', '#gn-job-order-deliver-form', function (e) {
        e.preventDefault();
        let _this = $(this);
        let _id = _this.find('input[name="order_id"]').val();
        let type = _this.find('select[name="order_delivery_type"]').val();
        let description = _this.find('textarea[name="order_delivery_description"]').val();
        let submit_btn = _this.find('button[type="submit"]');
        let proceed = true;
        let { files, uploader } = job_order_delivery_plupload;

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

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

        if (!files || !_id) {
            GigneoAlert.toast({
                icon: 'error',
                title: GigneoCommon.error,
                text: GigneoCommon.required_fields
            });
            proceed = false;
        }

        if (!proceed) {
            return;
        }

        let form_data = new FormData();
        form_data.append('action', 'gigneo_job_order_deliver');
        form_data.append('security', GigneoCommon.security);
        form_data.append('order_id', _id);
        form_data.append('type', type);
        form_data.append('description', description);

        if (uploader && files.length > 0) {
            files.forEach(function (file, i) {
                form_data.append('attachments[]', file.getNative(), file.name);
            });
        }

        submit_btn.addClass('gn-loading').attr('disabled', true);

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

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

                location.reload();

            },
            error: function (response) {
                submit_btn.removeClass('gn-loading').attr('disabled', false);
                GigneoAlert.toast({
                    icon: 'error',
                    title: GigneoCommon.error,
                    text: response.responseJSON && response.responseJSON.data && response.responseJSON.data.message ? response.responseJSON.data.message : ''
                });
            },
        });

    });

    //Job Order Revision
    $(document).on('submit', '#gn-job-order-revision-form', function (e) {
        e.preventDefault();
        let _this = $(this);
        let _id = _this.find('input[name="order_id"]').val();
        let description = _this.find('textarea[name="order_revision_description"]').val();
        let submit_btn = _this.find('button[type="submit"]');
        let { files, uploader } = job_order_attachments_plupload;
        let proceed = true;

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

        if (!proceed) {
            return false;
        }

        let form_data = new FormData();
        form_data.append('action', 'gigneo_job_order_revision');
        form_data.append('security', GigneoCommon.security);
        form_data.append('order_id', _id);
        form_data.append('description', description);

        if (uploader && files.length > 0) {
            files.forEach(function (file, i) {
                form_data.append('attachments[]', file.getNative(), file.name);
            });
        }

        submit_btn.addClass('gn-loading').attr('disabled', true);

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

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

                location.reload();

            },
            error: function (response) {
                submit_btn.removeClass('gn-loading').attr('disabled', false);
                GigneoAlert.toast({
                    icon: 'error',
                    title: GigneoCommon.error,
                    text: response.responseJSON && response.responseJSON.data && response.responseJSON.data.message ? response.responseJSON.data.message : ''
                });
            },
        });

    })

    //Approve Job Order Delivery
    $(document).on('click', '#gn-job-order-delivery-approve', function (e) {
        e.preventDefault();
        let _this = $(this);
        let order_id = _this.data('gn-order-id');

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

        GigneoAlert.confirm({
            icon: "warning",
            text: GigneoDashboard.approve_delivery_confirmation_desc,
            confirmButtonText: GigneoCommon.approve,
            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_job_order_delivery_approve',
                            id: order_id,
                            security: GigneoCommon.security
                        },
                        success: function (response) {
                            confirmBtn.classList.remove('gn-loading');
                            confirmBtn.disabled = false;

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

                            location.reload();
                            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();
                        }
                    });
                });
            }
        });

    });

    //Submit Job Order Feedback
    $(document).on('submit', '.gn-job-order-detail #gn-freelancer-review-form, .gn-job-order-detail #gn-employer-review-form', function (e) {
        e.preventDefault();

        let _this = $(this);
        let proceed = true;
        let form_data = new FormData(_this[0]);
        form_data.append('action', 'gigneo_job_order_review');
        form_data.append('security', GigneoCommon.security);
        let submit_btn = _this.find('button[type="submit"]');

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

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

        if (!proceed) {
            return false;
        }

        submit_btn.addClass('gn-loading');

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

                if (response.success) {
                    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
                });
            }
        });
    });

    //Complete Job Order
    $(document).on('click', '#gn-job-order-complete', function (e) {
        e.preventDefault();
        let _this = $(this);
        let order_id = _this.data('gn-order-id');

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

        GigneoAlert.confirm({
            icon: "warning",
            text: GigneoCommon.complete_confirmation_desc,
            confirmButtonText: GigneoCommon.complete,
            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_job_order_complete',
                            id: order_id,
                            security: GigneoCommon.security
                        },
                        success: function (response) {
                            confirmBtn.classList.remove('gn-loading');
                            confirmBtn.disabled = false;

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

                            location.reload();
                            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();
                        }
                    });
                });
            }
        });

    });

    //Cancel Job Order
    $(document).on('click', '#gn-job-order-cancel-btn', function (e) {
        e.preventDefault();
        let _this = $(this);
        let order_id = _this.data('gn-order-id');

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

        GigneoAlert.confirm({
            icon: "error",
            text: GigneoCommon.cancel_confirmation_desc,
            confirmButtonText: GigneoCommon.cancel,
            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_job_order_cancel',
                            order_id: order_id,
                            security: GigneoCommon.security
                        },
                        success: function (response) {
                            confirmBtn.classList.remove('gn-loading');
                            confirmBtn.disabled = false;

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

                            location.reload();
                            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();
                        }
                    });
                });
            }
        });

    });

    //Cancel Job Order Request
    $(document).on('submit', '#gn-job-order-cancel-request-form', function (e) {
        e.preventDefault();

        let _this = $(this);
        let proceed = true;
        let form_data = new FormData(_this[0]);
        form_data.append('action', 'gigneo_job_order_cancel');
        form_data.append('security', GigneoCommon.security);
        let submit_btn = _this.find('button[type="submit"]');

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

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

        if (!proceed) {
            return false;
        }

        submit_btn.addClass('gn-loading');

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

                if (response.success) {
                    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
                });
            }
        });
    });

    //Cancel Job Order Request Respond
    $(document).on('click', '.gn-job-order-detail #gn-job-order-cancel-approve,.gn-job-order-detail #gn-job-order-cancel-decline', function (e) {
        e.preventDefault();
        let _this = $(this);
        let btn_id = _this.attr('id');
        let order_id = _this.data('gn-order-id');
        let type = 'gn-job-order-cancel-approve' === btn_id ? 'approve' : 'decline';

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

        GigneoAlert.confirm({
            icon: "decline" === type ? "error" : "warning",
            text: "decline" === type ? GigneoDashboard.decline_cancel_request_confirmation_desc : GigneoDashboard.approve_cancel_request_confirmation_desc,
            confirmButtonText: "decline" === type ? GigneoCommon.decline : GigneoCommon.approve,
            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_job_order_cancel_respond',
                            order_id: order_id,
                            type: type,
                            security: GigneoCommon.security
                        },
                        success: function (response) {
                            confirmBtn.classList.remove('gn-loading');
                            confirmBtn.disabled = false;

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

                            location.reload();
                            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();
                        }
                    });
                });
            }
        });

    });



    /* ===================================
        Chat State Management
    ====================================== */
    if (GigneoCommon.active_modules.includes('live_chat')) {
        $(document).on("click", ".gn-message-request", function (e) {
            e.preventDefault();
            let _this = $(this);
            const profileId = _this.data("profile-id");
            const memberProfileId = _this.data("member-id");
            _this.addClass("gn-loading");
            if (profileId && memberProfileId) {
                // Make AJAX call to send Message request
                $.ajax({
                    url: GigneoCommon.ajax_url,
                    type: "POST",
                    data: {
                        action: "gigneo_add_member",
                        profile_id: profileId,
                        member_profile_id: memberProfileId,
                        security: GigneoCommon.security,
                    },
                    success: function (response) {
                        _this.removeClass("gn-loading");
                        window.location.href = response.data.dashboard_url;
                    },
                    error: function (xhr, status, error,) {
                        _this.removeClass("gn-loading");
                        // Handle error
                        GigneoAlert.toast({
                            icon: 'error',
                            title: GigneoCommon.error,
                            text: error.message || GigneoCommon.went_wrong
                        });
                        console.error("AJAX Error adding Member:", status, error);
                    },
                });
            }
        });
    }
    const chatState = {
        offset: 0,
        limit: parseInt(GigneoCommon.order_messages_limit) || 50,
        total: 0,
        isLoading: false,
        allLoaded: false,
        receiverId: $('#gn-receiver-profile-id').val() || null,
        orderId: $('#gn-chat-order-id').val() || null,
        ws_port: 8081,
    };

    /* ===================================
         Chat JS selectors
    ====================================== */

    // Send Message
    $(document).on('click', '.gn-order-message-wrapper #gn-send-message-btn', function (e) {
        e.preventDefault();
        order_chat_message(this);
    });

    function order_chat_message(btn) {
        let _this = $(btn);
        let submitBtn = $('.gn-order-message-wrapper #gn-send-message-btn');
        let wrapper = _this.parents('.gn-send-message-form');
        let editor = tinymce.get('gn-order-message');
        let message = editor.getContent();
        let order_id = wrapper.find('[name="order_id"]').val();
        let reply_id = wrapper.find('[name="reply_message_id"]').val();
        let receiver_profile_id = wrapper.find('[name="receiver_profile_id"]').val();


        if (message === '' || order_id === '') {
            GigneoAlert.toast({
                icon: 'error',
                title: GigneoCommon.error,
                text: GigneoCommon.required_fields
            });
            return false;
        }

        let formData = new FormData();
        formData.append('action', 'gigneo_send_order_message');
        formData.append('security', GigneoCommon.security);
        formData.append('order_id', order_id);
        formData.append('reply_id', reply_id);
        formData.append('receiver_profile_id', receiver_profile_id);
        formData.append('message', message);

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

        $.ajax({
            url: GigneoCommon.ajax_url,
            method: 'POST',
            data: formData,
            contentType: false,
            processData: false,
            success: function (response) {
                $('.gn-order-message-wrapper #gn-send-message-btn').removeClass('gn-loading').prop('disabled', false);
                wrapper.find('#gn-reply-user-shadow-wrapper').html('');

                if (response.success) {
                    renderMessages(response.data.markup);
                    scrollToNewMessage();

                    let editor = tinymce.get('gn-order-message');
                    if (editor) {
                        editor.setContent('');
                    }
                } else {
                    GigneoAlert.toast({
                        icon: 'error',
                        title: GigneoCommon.error,
                        text: response.data?.message || GigneoCommon.went_wrong
                    });
                }
            },
            error: function (xhr, status, error) {
                $('.gn-order-message-wrapper #gn-send-message-btn').removeClass('gn-loading').prop('disabled', false);

                let message = '';

                try {
                    const res = JSON.parse(xhr.responseText);
                    message = res.data?.message || res.message || GigneoCommon.went_wrong;
                } catch (e) {
                    message = GigneoCommon.went_wrong;
                }

                GigneoAlert.toast({
                    icon: 'error',
                    title: GigneoCommon.error,
                    text: message
                });
            }
        });
    }

    // Reply Message
    $(document).on('click', '.gn-message-reply-action .gn-message-reply', function (e) {
        e.preventDefault();
        let _this = $(this);
        let _message = _this.closest('.gn-message-reply');
        let _messageId = _message.data('gn-reply-message') || '';
        let _messageContent = _message.data('gn-message-content') || '📄';
        let _userName = _message.data('gn-user-name') || 'Unknown';
        let _messageTime = _message.data('gn-date-time') || '';
        let wrapper = $('.gn-message-input-wrapper');
        wrapper.find('[name="reply_message_id"]').val(_messageId);

        const replyHtml = `
                    <li class="gn-reply-user-shadow" id="gn-reply-user-shadow" data-gn-reply-to="${_messageId}">
                        <span class="close-replay-shadow"><i class="hi hi-x-mark"></i></span>
                        <div class="gn-replay-content">
                            <h4 class="gn-name">${_userName}<span class="gn-time"> ${_messageTime}</span></h4> 
                            <p class="gn-content">${_messageContent}</p>
                        </div>
                    </li>
                    
                `;
        $('#gn-reply-user-shadow-wrapper').html(replyHtml);

    });
    // Close Reply Shadow
    $(document).on('click', '.gn-reply-user-shadow .close-replay-shadow', function (e) {
        e.preventDefault();
        let wrapper = $('.gn-send-message-form');
        wrapper.find('[name="reply_message_id"]').val('');
        wrapper.find('#gn-reply-user-shadow-wrapper').html('');
    });

    $(document).on('click', '#order-message-indicator', function () {
        scrollToNewMessage();
        $(this).hide();
    });

    $(document).on('click', '#gn-message-wysiwyg', function () {
        let _chat_input = $('.gn-order-message-input-inner');
        _chat_input.toggleClass('gn-active');
    });

    $(document).on('change', '#gn-per-page', function () {
        let _this = $(this).val();
        let currentUrl = window.location.href;

        var newUrl = new URL(currentUrl);
        newUrl.searchParams.set('per_page', _this);
        window.location.href = newUrl.toString();
    });

    $(document).ready(bindScrollEvent);
    $(document).ready(scrollToNewMessage);
    $(document).ready(orderTinymceInit);

    /* ===================================
        Chat Functions
    ====================================== */

    function bindScrollEvent() {
        const $body = $('#gn-order-messages-body');
        if ($body.length) {
            $body.off('scroll').on('scroll', debounce(function () {
                if ($body.scrollTop() <= 10) {
                    loadMoreMessages();

                }
            }, 200));
        }
    }

    function debounce(func, wait) {
        let timeout;
        return function (...args) {
            clearTimeout(timeout);
            timeout = setTimeout(() => func.apply(this, args), wait);
        };
    }

    function orderTinymceInit() {
        if (typeof tinymce === 'undefined') {
            return;
        }

        if (tinymce.get('gn-order-message')) {
            tinymce.get('gn-order-message').remove();
        }
        let _chat_input = $('.gn-order-message-input-inner');
        let submitBtn = $('.gn-order-message-wrapper #gn-send-message-btn');
        tinymce.init({
            selector: '#gn-order-message',
            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,
            setup: function (editor) {
                editor.on('keydown', function (e) {
                    if (e.key === 'Enter' && !e.shiftKey) {
                        if (!_chat_input.hasClass('gn-active')) {
                            e.preventDefault(); // Stop new line
                            const message = editor.getContent({ format: 'text' }).trim();
                            if (message) {
                                order_chat_message(submitBtn);
                                editor.setContent('');
                            }
                        }
                    }
                });
            },

        });
    }

    function handleNewMessage() {

        const receiver_id = parseInt(chatState.receiverId, 10);
        const order_id = $('#gn-chat-order-id').val();

        $.ajax({
            url: GigneoCommon.ajax_url,
            method: 'POST',
            data: {
                action: 'gigneo_get_order_message',
                security: GigneoCommon.security,
                receiver_id: receiver_id,
                order_id: order_id,
                offset: 0,
                limit: chatState.limit
            },
            success: function (response) {
                if (response.success && response.data.markup && response.data.total > 0) {
                    // Use the existing appendMessages function from live-chat.js
                    if (typeof appendOrderMessages === 'function') {
                        appendOrderMessages(response.data.markup);
                    }
                }
            },
            error: function () {
                console.error('Error fetching messages.');
            }
        });

    }

    function scrollToNewMessage() {
        const $body = $('#gn-order-messages-body');
        if ($body.length) {
            $body.scrollTop($body[0].scrollHeight);
        }
    }

    function appendOrderMessages(markup) {
        const parser = new DOMParser();
        const $body = $('#gn-order-messages-body');
        const $container = $('#gn-order-messages-body .gn-messages-wrapper');

        if (markup && markup.body && $body.length && $container.length) {
            const isAtBottom = $body.scrollTop() + $body.innerHeight() >= $body[0].scrollHeight - 10;
            const body = parser.parseFromString(markup.body, 'text/html');
            const newContent = body.querySelector('#gn-order-messages-body');
            const newMessages = body.querySelectorAll('.gn-messages-wrapper .gn-message');

            const existingMessages = {};
            $container.find('.gn-message').each(function () {
                const id = $(this).data('gn-message-id');
                if (id) existingMessages[id] = $(this);
            });

            let addedNewMessage = false;

            newMessages.forEach(newMsg => {
                const msgId = newMsg.dataset.gnMessageId;
                const $existing = existingMessages[msgId];
                if ($existing && $existing.length) {
                    const newHtml = newMsg.outerHTML.trim();
                    const currentHtml = $existing[0].outerHTML.trim();
                    if (newHtml !== currentHtml) {
                        $existing.replaceWith(newHtml);
                    }
                } else {
                    let inserted = false;
                    const newId = parseInt(msgId, 10);
                    $container.find('.gn-message').each(function () {
                        const existingId = parseInt($(this).data('gn-message-id'), 10);
                        if (newId < existingId) {
                            $(this).before(newMsg.outerHTML);
                            inserted = true;
                            return false;
                        }
                    });
                    if (!inserted) {
                        $container.append(newMsg.outerHTML);
                    }
                    addedNewMessage = true;
                }
            });

            if (addedNewMessage) {
                if ($container.find('.gn-message').length <= 1 && newContent) {
                    $body.html(newContent.innerHTML);
                    scrollToNewMessage();
                } else {
                    if (isAtBottom) {
                        scrollToNewMessage();
                    } else {
                        newOrderMessageIndicator();
                    }
                }
            }
        }
        bindScrollEvent();
        orderTinymceInit();
    }

    function newOrderMessageIndicator() {
        const $body = $('#gn-order-messages-body');
        const isAtBottom = $body.scrollTop() + $body.innerHeight() >= $body[0].scrollHeight - 10;
        let $newMessageIndicator = $('#order-message-indicator');
        $newMessageIndicator.hide();
        if (!isAtBottom) {
            if (!$newMessageIndicator.length) {
                $body.after(`<div class="gn-order-new-message" id="order-message-indicator">
                    <i class="hi hi-arrow-long-down"></i>
                </div>`);
            } else {
                $newMessageIndicator.show();
            }
        }
    }

    function loadMoreMessages() {
        if (chatState.isLoading || chatState.allLoaded) return;
        const { receiverId, offset, limit } = chatState;
        const $body = $('#gn-order-messages-body');
        const $messages = $body.find('.gn-messages-wrapper');
        const prevScrollHeight = $body[0].scrollHeight;
        const prevScrollTop = $body.scrollTop();

        $messages.prepend(`
            <div class="gn-chat-loading">
				<svg xmlns="http://www.w3.org/2000/svg" width="36" height="36" viewBox="0 0 36 36" fill="none">
					<rect x="16.9596" y="0.5" width="2.91667" height="8.75" rx="1.45833" class="gn-chat-loader-animation"></rect>
					<rect x="16.9596" y="26.75" width="2.91667" height="8.75" rx="1.45833" class="gn-chat-loader-animation gn-delay-1"></rect>
					<rect x="0.917969" y="19.4585" width="2.91667" height="8.75" rx="1.45833" transform="rotate(-90 0.917969 19.4585)" class="gn-chat-loader-animation gn-delay-2"></rect>
					<rect x="27.168" y="19.4585" width="2.91667" height="8.75" rx="1.45833" transform="rotate(-90 27.168 19.4585)" class="gn-chat-loader-animation gn-delay-3"></rect>
					<rect x="5.01245" y="6.65674" width="2.91667" height="8.75" rx="1.45833" transform="rotate(-45 5.01245 6.65674)" class="gn-chat-loader-animation gn-delay-4"></rect>
					<rect x="23.574" y="25.2183" width="2.91667" height="8.75" rx="1.45833" transform="rotate(-45 23.574 25.2183)" class="gn-chat-loader-animation gn-delay-5"></rect>
					<rect x="7.07471" y="31.4058" width="2.91667" height="8.75" rx="1.45833" transform="rotate(-135 7.07471 31.4058)" class="gn-chat-loader-animation gn-delay-6"></rect>
					<rect x="25.6362" y="12.8438" width="2.91667" height="8.75" rx="1.45833" transform="rotate(-135 25.6362 12.8438)" class="gn-chat-loader-animation gn-delay-7"></rect>
				</svg>
			</div>
        `);

        fetchMessages(receiverId, offset, limit, false, true);
    }

    function renderMessages(markup) {
        if (!markup || typeof markup !== 'object') return;
        Object.entries(markup).forEach(([key, html]) => {
            const $temp = $('<div>').html(html);
            const $newContent = $temp.find(`#gn-order-messages-${key}`);
            const $existing = $(`#gn-order-messages-${key}`);
            // Replace only if both elements exist
            if ($existing.length && $newContent.length) {
                $existing.replaceWith($newContent);
            }
        });
        bindScrollEvent();
        orderTinymceInit();
        const $lastMessage = $('#gn-order-messages-body .gn-messages-wrapper .gn-message').last();
        if ($lastMessage.length) {
            chatState.lastMessageId = $lastMessage.data('gn-message-id');
        }
    }

    function loadMoreMessagesCallback(data) {
        const $body = $('#gn-order-messages-body');
        const $messages = $body.find('.gn-messages-wrapper');
        const prevScrollHeight = $body[0].scrollHeight;
        const prevScrollTop = $body.scrollTop();

        $messages.find('.gn-chat-loading').remove();
        if (data && data.markup) {
            const $newMessages = $(data.markup.body).find('.gn-messages-wrapper .gn-message');
            const existingMessageIds = $messages.find('.gn-message').map((_, el) => $(el).data('gn-message-id')).get();
            const newMessages = $newMessages.filter((_, el) => !existingMessageIds.includes($(el).data('gn-message-id')));
            if (newMessages.length > 0) {
                $messages.append(newMessages);
                chatState.offset += newMessages.length;
                if (chatState.offset >= chatState.total) {
                    chatState.allLoaded = true;
                }
                const newScrollHeight = $body[0].scrollHeight;
                $body.scrollTop(newScrollHeight - prevScrollHeight + prevScrollTop);
            } else {
                chatState.allLoaded = true;
            }
        } else {
            chatState.allLoaded = true;
        }
        bindScrollEvent();
        orderTinymceInit();
    }

    function fetchMessages(receiverId, offset = 0, limit = 10, initial = false, prepend = false) {
        if (!receiverId) {
            console.error('[fetchMessages] Receiver ID is required');
            return;
        }

        chatState.isLoading = true;
        const user_id = $('#gn-receiver-profile-id').val();
        const order_id = $('#gn-chat-order-id').val();


        $.ajax({
            url: GigneoCommon.ajax_url,
            method: 'POST',
            data: {
                action: 'gigneo_get_order_message',
                security: GigneoCommon.security,
                receiver_id: user_id,
                order_id: order_id,
                offset,
                limit
            },
            success: function (response) {
                if (response.success) {
                    const { data } = response;
                    if (data?.total !== undefined) {
                        chatState.total = parseInt(data.total, 10);
                    }
                    if (initial) {
                        if (data?.total === "0") {
                            renderMessages(data?.markup || '');
                            orderTinymceInit();
                        }
                    } else if (prepend) {
                        loadMoreMessagesCallback(data);
                        orderTinymceInit();
                    }
                } else {
                    if (initial || !prepend) {
                        renderMessages('');
                    }
                    GigneoAlert.toast({
                        icon: 'error',
                        title: GigneoCommon.error,
                        text: response.data?.message || GigneoCommon.went_wrong
                    });
                }
            },
            error: function () {
                GigneoAlert.toast({
                    icon: 'error',
                    title: GigneoCommon.error,
                    text: GigneoCommon.went_wrong
                });
            },
            complete: function () {
                chatState.isLoading = false;
            }
        });
    }


    function handleHeartbeatMessage(event, data) {
        if (!data || typeof data['gigneo_order_messages_count'] === 'undefined') {
            return;
        }

        const user_id = $('#gn-receiver-profile-id').val();
        const order_id = $('#gn-chat-order-id').val();

        if (user_id) {
            $.ajax({
                url: GigneoCommon.ajax_url,
                method: 'POST',
                data: {
                    action: 'gigneo_get_order_message',
                    security: GigneoCommon.security,
                    order_id: order_id,
                    receiver_id: user_id,
                    offset: 0,
                    limit: GigneoCommon.order_messages_limit || 50,
                },
                success: function (response) {
                    if (response.success && response.data.markup && response.data.total.length > 0) {
                        appendOrderMessages(response.data.markup);
                        chatState.total = response.data.total;
                    }
                },
                error: function () {
                    console.error('Error fetching messages during heartbeat');
                }
            });
        }
    }

    let last_unread_order_messages = parseInt($('.gn-tab-list-item[href*="tab=messages"]').siblings('.gn-count').text()) || 0;
    let last_check = null;

    if ('heartbeat' === GigneoCommon.notification_type) {
        if (typeof wp !== "undefined" && wp.heartbeat) {
            wp.heartbeat.interval(GigneoCommon.heartbeat_interval);
        }

        const is_logged_in = parseInt(GigneoCommon.profile_id, 10);

        if (!is_logged_in || isNaN(is_logged_in)) {
            return;
        }

        // Send data with Heartbeat
        $(document).on('heartbeat-send', function (e, data) {
            data['gigneo_order_messages'] = true;
            $(document).trigger('gigneo_heartbeat_send', data);
        });

        // Handle Heartbeat response
        $(document).on('heartbeat-tick', function (e, data) {
            if (data['gigneo_order_messages_count'] !== undefined) {
                let unread_messages = data['gigneo_order_messages_count'] ?? 0;
                if (unread_messages !== last_unread_order_messages) {

                    // Update DOM Count
                    let count_element = $('.gn-tab-list-item[href*="tab=messages"]').siblings('.gn-count');
                    if (count_element.length) {
                        count_element.text(unread_messages);
                    }

                    handleHeartbeatMessage(e, data);
                }
                last_unread_order_messages = unread_messages;
            }
        });
    }

    /* ===================================
         Notes Support Functionality
    ====================================== */

    //Edit/Add Note
    $(document).on('submit', '#gn-order-private-note-form', function (e) {
        e.preventDefault();

        let _this = $(this);
        let proceed = true;
        let note_modal = $('#gn-order-note-modal');

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

        let form_data = new FormData(_this[0]);
        form_data.append('action', 'gigneo_order_private_note');
        form_data.append('security', GigneoCommon.security);
        let submit_btn = _this.find('button[type="submit"]');

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

        if (proceed) {
            submit_btn.addClass('gn-loading');

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

                        Object.entries(response.data.markup).forEach(([key, html]) => {
                            const $wrapper = $(`#gn-order-${key} .gn-private-note-body`);
                            if ($wrapper.length && $(html).length) {
                                $wrapper.html($(html).find('.gn-private-note-body').html());
                            }
                            tinymce?.get('gn-order-note')?.setContent('');
                            initPrivateNoteSlider();
                            initNoteTinymceInit();
                        });
                    } else {
                        GigneoAlert.toast({
                            icon: 'error',
                            title: GigneoCommon.error,
                            text: response.data?.message || GigneoCommon.went_wrong
                        });
                    }
                    location.reload();
                },
                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
                    });
                }
            });
        }

    });

    //Delete note
    $(document).on('click', '.gn-delete-private-note', function (e) {
        e.preventDefault();
        let _this = $(this);
        let note_id = _this.data('gn-note-id');
        let order_id = _this.data('gn-order-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_delete_private_note',
                            note_id: note_id,
                            order_id: order_id,
                            security: GigneoCommon.security
                        },
                        success: function (response) {
                            confirmBtn.classList.remove('gn-loading');
                            confirmBtn.disabled = false;

                            if (response.success) {
                                Object.entries(response.data.markup).forEach(([key, html]) => {
                                    const $wrapper = $(`#gn-order-${key} .gn-private-note-body`);
                                    if ($wrapper.length && $(html).length) {
                                        $wrapper.html($(html).find('.gn-private-note-body').html());
                                    }
                                    initPrivateNoteSlider();
                                    initNoteTinymceInit();
                                });
                                if (response.data.message) {
                                    GigneoAlert.toast({
                                        icon: 'success',
                                        title: GigneoCommon.success,
                                        text: response.data.message
                                    });
                                }
                            }
                            resolve();
                            location.reload();
                            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
                            });
                            resolve();
                            location.reload();
                            return Promise.resolve();
                        }
                    });
                });
            }
        });

    });

    //Edit modal before open data
    $(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-order-note-modal')) {
            if (fields !== undefined) {
                if (typeof fields === 'object') {
                    $.each(fields, function (key, value) {
                        let field = selector.find(`[name="${key}"]`);
                        if (field.length) {
                            let field_id = field.attr('id');
                            // If it's a TinyMCE editor
                            if (typeof tinymce !== 'undefined' && tinymce.get(field_id)) {
                                tinymce.get(field_id).setContent((JSON.parse(value)));
                            } else {
                                // Normal input/textarea
                                field.val(value);
                            }
                        }
                    });
                }
            }
        }

    });

    function initPrivateNoteSlider() {
        let slider = $('.gn-private-note-slider-wrapper');

        slider.slick({
            slidesToShow: 1,
            slidesToScroll: 1,
            arrows: false,
            dots: true,
            infinite: true,
            adaptiveHeight: true,
            rtl: $('html').attr('dir') === 'rtl'
        });

    }

    function initNoteTinymceInit() {
        if (typeof tinymce === 'undefined') {
            return;
        }
        if (tinymce.get('gn-order-note')) {
            tinymce.get('gn-order-note').remove();
            tinymce.init({
                selector: '#gn-order-note',
                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,
            });
        }
    }

    initPrivateNoteSlider();
    initNoteTinymceInit();

    /* ===================================
       Heart Beat
    ====================================== */
    $(document).on('gigneo_heartbeat_trigger', function (e, data) {
        const current_order_id = parseInt($('#gn-chat-order-id').val(), 10);
        if (data && data.gigneo_onscreen_notifications && data.gigneo_onscreen_notifications.length > 0) {
            const has_new_message = data.gigneo_onscreen_notifications.some(notification => {
                return notification.category === 'order' &&
                       notification.type === 'message' &&
                       parseInt(notification.post_id, 10) === current_order_id;
            });
            if (has_new_message) {
                let no_message_body = $('.gn-messages.gn-no-message');
                if (no_message_body.length) {
                    no_message_body.remove();
                }
                handleNewMessage();
            }
        }
    });

    $(document).on('gigneo_realtime_order_message', function () {
        let no_message_body = $('.gn-messages.gn-no-message');
        if (no_message_body.length) {
            no_message_body.remove();
        }
        handleNewMessage();
    });

    /* ===================================
       Job Delivery uploader
    ====================================== */

    //Job Order Delivery uploader
    const job_order_delivery_plupload = GigneoPlupload.init({
        browseButtonId: 'gn-job-order-delivery-uploader',
        containerId: 'gn-job-order-delivery-container',
        dropElementId: 'gn-job-order-delivery-drop-area',
        attachmentListId: 'gn-job-order-delivery-list',
        allowedExtensions: GigneoDashboard.job_order_extensions || ['jpg,jpeg,png,doc'],
        maxFiles: GigneoDashboard.job_order_max_files || '3',
        maxSizeMb: GigneoDashboard.job_order_max_size || '1',
        errorMessages: {
            maxFiles: GigneoDashboard.job_order_max_files_notice,
            invalidExtension: GigneoDashboard.job_order_extension_notice,
            maxSize: GigneoDashboard.job_order_max_size_notice
        }
    });

    //Service Order Delivery uploader
    const service_order_delivery_plupload = GigneoPlupload.init({
        browseButtonId: 'gn-service-order-delivery-uploader',
        containerId: 'gn-service-order-delivery-container',
        dropElementId: 'gn-service-order-delivery-drop-area',
        attachmentListId: 'gn-service-order-delivery-list',
        allowedExtensions: GigneoDashboard.service_order_extensions || ['jpg,jpeg,png,doc'],
        maxFiles: GigneoDashboard.service_order_max_files || '3',
        maxSizeMb: GigneoDashboard.service_order_max_size || '1',
        errorMessages: {
            maxFiles: GigneoDashboard.service_order_max_files_notice,
            invalidExtension: GigneoDashboard.service_order_extension_notice,
            maxSize: GigneoDashboard.service_order_max_size_notice
        }
    });
    


}(jQuery));