function jsonShippingMethodsRowHtmlMacker(isArrayItem, json) { //dont use ids because ids cant be repeated in DOM
    let htmlRow = "";
    htmlRow += '<div class="json_shipping_methods_card card card-outline card-json-item collapsed-card global-json-handler-card">';
    htmlRow += '<div class="card-header json_shipping_methods_box">';
    htmlRow += '<div class="textcontainer">';
    if (isArrayItem) htmlRow += '<div class="my-handle"><i class="ph ph-caret-up-down"></i></div>';
    htmlRow += '<img class="json_logo_showimg" style="height:40px;width: auto;" src="' + (json != null ? json['logo'] : "") + '">';
    htmlRow += '<span class="name_showtext" >' + (json != null ? json['name'] : "") + '</span>';
    htmlRow += '<span class="method_code_showtext" >' + (json != null ? json['method_code'] : "") + '</span>';
    htmlRow += '</div>';
    htmlRow += '<div class="card-tools2">';
    htmlRow += '<button type="button" class="all_json_shipping_methods_edit_btn btn btn-primary btn-sm"><i class="ph ph-pencil"></i></button>';
    if (isArrayItem) htmlRow += '<button type="button" class="all_json_shipping_methods_delete_btn btn btn-danger btn-sm"><i class="la la-trash"></i></button>';
    htmlRow += '</div>';
    htmlRow += '</div>';
    htmlRow += '<div class="card-body" style="display: none;">';

    htmlRow += textInputHtmlGenerator((json != null ? json['method_code'] : "") , "js_code_txt", "کد");
    htmlRow += '<div class="notes bottom20">کد باید بصورت انگلیسی و بدون فاصله یا اسپیس وارد شود </div>';

    htmlRow += textInputHtmlGenerator((json != null ? json['name'] : "") , "js_name_txt", "عنوان روش ارسال");
    
    htmlRow += textInputHtmlGenerator((json != null ? json['description'] : "") , "js_description_txt", "توضیحات مختصر");

    let options = {
        online: "پرداخت آنلاین",
        atdes: "پس‌کرایه"
    }
    let value = (json != null) ? json['payment_way'] : null;
    htmlRow += rowOptionsInputHtmlGenerator(value,options,"js_payment_way_txt","روش پرداخت هزینه حمل");

    let options2 = {
        non_local: "مشتریان غیربومی",
        local: "مشتریان بومی",
        none: "هیچ",
        all: "همه"
    }
    let value2 = (json != null) ? json['visible_for'] : null;
    htmlRow += rowOptionsInputHtmlGenerator(value2,options2,"js_visible_for_txt","نمایش برای");

    htmlRow += numberPriceInputHtmlGenerator((json != null ? json['price'] : ""), "js_price_txt", "هزینه");
    htmlRow += numberPriceInputHtmlGenerator((json != null ? json['free_shipping_minimum'] : ""), "js_free_shipping_minimum_txt", "حداقل خرید برای رایگان شدن هزینه حمل");
 

    let imgClass = 'js_shipping_logo_img';
    let imgId = 'cat-image-' + randomUID(21);
    let imgUrl = (json != null ? json['logo'] : "");
    htmlRow += imageInputHtmlGenerator(imgUrl, imgClass, imgId, "تصویر آیکون (اختیاری)");

    htmlRow += '<span class="minitext">بعد از ایجاد تغییرات بروی این آیتم، بروی ثبت تغییرات کلیک کنید. دقت کنید ثبت تغییرات به معنی ذخیره در سرور نمیباشد</span>';
    htmlRow += '<div class="local_submit_parent">';
    htmlRow += '<span class="' + (isArrayItem ? "json_shipping_methods_submit_array" : "json_shipping_methods_submit") + ' btn btn-primary btn-sm">ثبت تغییرات</span>';
    htmlRow += '<span class="json_shipping_methods_cancel btn btn-gray btn-sm">انصراف</span>';
    htmlRow += '</div>';
    htmlRow += '</div>';
    htmlRow += '</div>';

    return htmlRow;
}

function shippingMethodsSortableChange(){

    let root_of_current = $('.json_handler_shipping_methods_array');
    let textarea = root_of_current.find('.json_text_area');
    const sortableList = root_of_current.find('#shipping_methods_sortable_list');

    let arr = [];
    sortableList.children().each(function (i, li) {

        const card = $(li);
        let _code = card.find('.js_code_txt').val();
        let _name = card.find('.js_name_txt').val();
        let _price = card.find('.js_price_txt').val();
        let _description = card.find('.js_description_txt').val();
        let _free_shipping_minimum = card.find('.js_free_shipping_minimum_txt').val();
        let _visible_for = card.find('.js_visible_for_txt').val();
        let _payment_way = card.find('.js_payment_way_txt').val();
        let _logo = card.find('.js_shipping_logo_img').val();


        let obj = {
            method_code: _code,
            payment_way: _payment_way,
            name: _name,
            description: _description,
            visible_for: _visible_for,
            logo: _logo,
            price: _price,
            free_shipping_minimum: _free_shipping_minimum
        };
        if(!li.classList.contains('no-item-found')){
            arr[i] = obj;
        }
    });

    let stringjs = JSON.stringify(arr);

    textarea.val(stringjs);

    notyf.open({
        type: 'info',
        message: 'ترتیب آیتم‌ها ثبت شد، برای اعمال نهایی بروی ذخیره کلیک کنید.'
    });
    
}

let editJsonShippingMethodsRowsBtn = function () {
    
    let root_card = $(this).parent().parent().parent();
    root_card.find('.card-body').show('slideDown');
    $(this).hide();

};

function jsonShippingMethodsArraySubmitBtnHandler(IsSingleItemEdit, card) {
    
    let root_of_current = $('.json_handler_shipping_methods_array');
    let textarea = root_of_current.find('.json_text_area');
    const sortableList = root_of_current.find('#shipping_methods_sortable_list');
    
    root_of_current.find('.all_json_shipping_methods_edit_btn').show();
    
    //if we edit only single row and submiting it:
    if (IsSingleItemEdit) {

        let _code = card.find('.js_code_txt').val();
        let _name = card.find('.js_name_txt').val();
        let _price = card.find('.js_price_txt').val();
        let _description = card.find('.js_description_txt').val();
        let _free_shipping_minimum = card.find('.js_free_shipping_minimum_txt').val();
        let _visible_for = card.find('.js_visible_for_txt').val();
        let _logo = card.find('.js_shipping_logo_img').val();

        card.find('.json_logo_showimg').attr("src", _logo);
        card.find('.method_code_showtext').html(_code);
        card.find('.name_showtext').html(_name);

        card.addClass("collapsed-card");
        let card_body = card.find('.card-body');
        card_body.slideUp();
    }

    let arr = [];
    sortableList.children().each(function (i, li) {

        const card = $(li);
        let _code = card.find('.js_code_txt').val();
        let _name = card.find('.js_name_txt').val();
        let _price = card.find('.js_price_txt').val();
        let _description = card.find('.js_description_txt').val();
        let _free_shipping_minimum = card.find('.js_free_shipping_minimum_txt').val();
        let _visible_for = card.find('.js_visible_for_txt').val();
        let _payment_way = card.find('.js_payment_way_txt').val();
        let _logo = card.find('.js_shipping_logo_img').val();

        if (_price == "") _price = "0";

        let obj = {
            method_code: _code,
            payment_way: _payment_way,
            name: _name,
            description: _description,
            visible_for: _visible_for,
            logo: _logo,
            price: _price,
            free_shipping_minimum: _free_shipping_minimum
        };
        if(!li.classList.contains('no-item-found')){
            arr[i] = obj;
        }
    });

    let stringjs = JSON.stringify(arr);

    textarea.val(stringjs);

    notyf.open({
        type: 'info',
        message: 'تغییرات آرایه ای ثبت شد'
    });

};

const deleteJsonShippingMethodsRowsBtn = function () {

    const root_card = $(this).closest('.global-json-handler-card');
    const sortable_list = $(this).closest('.global-sortable-list');

    Swal.fire({
        title: 'این آیتم را حذف میکنید؟',
        icon: '',
        showCancelButton: true,
        confirmButtonColor: '#d33',
        cancelButtonColor: '#007bff',
        confirmButtonText: 'حذف آیتم',
        cancelButtonText: 'انصراف'
    }).then((result) => {
        if (result.isConfirmed) {

            root_card.remove();

            if (sortable_list.children().length == 0) {
                const htmlrow = ThereIsNoRowHereHtml();
                $(".json_handler_shipping_methods_array").find(".showbox").find("#shipping_methods_sortable_list").html(htmlrow);
            }

            //refresh textarea data:
            jsonShippingMethodsArraySubmitBtnHandler(false);

        }
    })
};

const jsonShippingMethodsCancelBtn = function () {
    
    let card = $(this).closest('.json_shipping_methods_card');
    card.find('.all_json_shipping_methods_edit_btn').show();
    card.addClass("collapsed-card");
    let card_body = card.find('.card-body');
    card_body.slideUp();

};

function jsonShippingMethodsArraySubmitBtn(event) {
    
    //https://stackoverflow.com/a/9467172/4565796
    IsSingleItemEdit = event.data.IsSingleItemEdit;
    let card = $(this).parent().parent().parent();
    jsonShippingMethodsArraySubmitBtnHandler(IsSingleItemEdit, card);

};

$('#add_shipping_methods_array_item').click(function () {

    const root = $(this).parent();
    root.find('.no-item-found').remove();

    const htmlrow = jsonShippingMethodsRowHtmlMacker(true, null);
    root.find(".showbox").find("#shipping_methods_sortable_list").prepend(htmlrow);

    $('.all_json_shipping_methods_edit_btn').click(editJsonShippingMethodsRowsBtn);
    $('.all_json_shipping_methods_delete_btn').click(deleteJsonShippingMethodsRowsBtn);
    $('.json_shipping_methods_submit_array').off("click");
    //https://stackoverflow.com/a/9467172/4565796
    $('.json_shipping_methods_submit_array').click({
        IsSingleItemEdit: true
    }, jsonShippingMethodsArraySubmitBtn);
    $('.json_shipping_methods_cancel').click(jsonShippingMethodsCancelBtn);
    $('.mppanel_image_url').on("input", changeImagePreview);
    $('.row-options-wrapper > .row-option').click(SelectRowOptionsChanged);
    $('input.ng-price-input').on('input change keyup paste',priceInputChanged);
    newGenImageHandler();

});


function buildShippingMethodsJsonAndSave() {

    let shipping_methods_data = $('#shipping_methods').val();

    if (
        (!shipping_methods_data) ||
        (shipping_methods_data.trim() == '') ||
        (shipping_methods_data.trim() == "") ||
        (shipping_methods_data.trim() == "null") ||
        (shipping_methods_data.trim() == "undefined") ||
        (shipping_methods_data.trim() == null)
    ) shipping_methods_data = "[]";

    let _toSave = {
        shipping_methods: $.trim(shipping_methods_data)
    }

    $.ajax({
        type: "POST",
        url: mpPanelBaseUrl + "/update-shipping-methods",
        data: _toSave,
        timeout: 25000,
        cache: false,
        success: function (data) {
            if (data == "ok") {
                notyf.success("ذخیره انجام شد");
                window.location.href = mpPanelBaseUrl + "/physical-store-settings/shipping-methods-management";
            } else {
                notyf.error(data);
            }
        },
        error: function (e) {
            notyf.error('Error: ' + e.responseText);
        }
    });
}

$(function () { // start of document ready:

    $('#shipping_methods_save').click(function () {

        Swal.fire({
            title: 'از ذخیره روشهای حمل و نقل مطمئن هستید؟',
            text: '',
            icon: '',
            showCancelButton: true,
            confirmButtonColor: '#007bff',
            cancelButtonColor: '#909090',
            confirmButtonText: 'بله',
            cancelButtonText: 'انصراف'
        }).then((result) => {
            if (result.isConfirmed) {

                buildShippingMethodsJsonAndSave();

            }
        })

    });

    const jsonShippingMethodsSubmitBtn = function () {

        let root_of_current = $(this).parent().parent().parent().parent().parent().parent();
        let textarea = root_of_current.find('.json_text_area');
        let card = $(this).parent().parent().parent();
    

        let _code = card.find('.js_code_txt').val();
        let _name = card.find('.js_name_txt').val();
        let _price = card.find('.js_price_txt').val();
        let _description = card.find('.js_description_txt').val();
        let _free_shipping_minimum = card.find('.js_free_shipping_minimum_txt').val();
        let _visible_for = card.find('.js_visible_for_txt').val();
        let _logo = card.find('.js_shipping_logo_img').val();

        if (_price == "") _price = "0";

        root_of_current.find('.all_json_shipping_methods_edit_btn').show();
    
        card.find('.json_logo_showimg').attr("src", _logo);
        card.find('.method_code_showtext').html(_code);
        card.find('.name_showtext').html(_name);

        let obj = {
            method_code: _code,
            name: _name,
            description: _description,
            visible_for: _visible_for,
            logo: _logo,
            price: _price,
            free_shipping_minimum: _free_shipping_minimum
        };

    
        let stringjs = JSON.stringify(obj);
    
        textarea.val(stringjs);
    
        card.addClass("collapsed-card");
        let card_body = card.find('.card-body');
        card_body.slideUp();
    
        notyf.open({
            type: 'info',
            message: 'تغییرات ثبت شد'
        });
    };
    

    $('.json_shipping_methods_submit').click(jsonShippingMethodsSubmitBtn);
    $('.json_shipping_methods_cancel').click(jsonShippingMethodsCancelBtn);

    if ($(".json_handler_shipping_methods_array")[0]) { //there is json type 1 array list:

        const jsonString = $.trim($('.json_handler_shipping_methods_array > textarea').val());
        let jsonShippingMethodsArrayObj;

        if (jsonString == '') {
            jsonShippingMethodsArrayObj = [];
        } else {
            jsonShippingMethodsArrayObj = JSON.parse(jsonString);
        }

        if (jsonShippingMethodsArrayObj.length == 0) {
            const htmlrow = ThereIsNoRowHereHtml();
            $(".json_handler_shipping_methods_array").find(".showbox").find("#shipping_methods_sortable_list").html(htmlrow);
        } else {
            $.each(jsonShippingMethodsArrayObj, function (key, value) {
                //console.log("vs: " + value);
                const htmlrow = jsonShippingMethodsRowHtmlMacker(true, value);
                $(".json_handler_shipping_methods_array").find(".showbox").find("#shipping_methods_sortable_list").append(htmlrow);
            });
        }

        $('.all_json_shipping_methods_edit_btn').click(editJsonShippingMethodsRowsBtn);
        $('.all_json_shipping_methods_delete_btn').click(deleteJsonShippingMethodsRowsBtn);
        $('.json_shipping_methods_submit_array').off("click");
        //https://stackoverflow.com/a/9467172/4565796
        $('.json_shipping_methods_submit_array').click({
            IsSingleItemEdit: true
        }, jsonShippingMethodsArraySubmitBtn);
        $('.json_shipping_methods_cancel').click(jsonShippingMethodsCancelBtn);
        $('.mppanel_image_url').on("input", changeImagePreview);
        $('.row-options-wrapper > .row-option').click(SelectRowOptionsChanged);
        $('input.ng-price-input').on('input change keyup paste',priceInputChanged);
        newGenImageHandler();
        
    }

    $('#shipping_methods_sortable_list').sortable({
        group: 'list',
        animation: 200,
        delay: 100, // time in milliseconds to define when the sorting should start
        delayOnTouchOnly: true, // only delay if user is using touch
        handle: ".my-handle", // Drag handle selector within list items
        ghostClass: 'ghost',
        onSort: shippingMethodsSortableChange
    });

}); //end of jqury doc ready