function cartActions() {
    const addToCartType = 'add-to-cart';
    const removeFromCartType = 'remove-from-cart';
    const updateCartQuantityType = 'update-cart-quantity';

    const addToCarts = document.querySelectorAll(`[data-type=${addToCartType}]`);
    addToCarts.forEach(addToCart => {
        if (addToCart.dataset.script === 'loaded') return;
        addToCart.dataset.script = 'loaded';

        addToCart.addEventListener('submit', async (e) => {
            e.preventDefault();
            if (addToCart.dataset.loading === 'true')
                return;

            const hasError = addToCart.querySelector(`[data-error=true]`);

            if (hasError) {
                addToCart.dataset.error = 'true';
                return;
            }

            const formData = new URLSearchParams();
            formData.append('action', 'ajax_add_to_cart');
            formData.append('security', ajax_add_to_cart_object.nonce);
            const form = new FormData(addToCart);
            for (let [name, value] of form.entries()) {
                formData.append(name, value);
            }

            const productId = formData.get('product_id');
            const quantity = formData.get('quantity');
            if (!productId) {
                console.error("You should set product_id input on 'add-to-cart' form");
                return;
            }
            if (!quantity) {
                console.error("You should set quantity input on 'add-to-cart' form");
                return;
            }

            addToCart.dataset.loading = 'true';
            const response = await fetch(ajax_add_to_cart_object.url, {
                method: "POST",
                body: formData,
                headers: {
                    'Content-Type': 'application/x-www-form-urlencoded',
                }
            });

            const data = await response.json();
            addToCart.dataset.loading = 'false';

            if (data.success) {
                Toastify({
                    text: 'محصول با موفقیت به سبد خرید اضافه شد.',
                    duration: 3000,
                    gravity: "top", // `top` or `bottom`
                    position: "center", // `left`, `center` or `right`
                    stopOnFocus: true, // Prevents dismissing of toast on hover
                    style: {
                        background: "var(--color-green-500)",
                        borderRadius: "8px",
                        fontSize: "var(--text-body-s)"
                    }
                }).showToast();

                jQuery(document.body).trigger('wc_fragment_refresh');
            } else {
                Toastify({
                    text: data.data,
                    duration: 3000,
                    gravity: "top", // `top` or `bottom`
                    position: "center", // `left`, `center` or `right`
                    stopOnFocus: true, // Prevents dismissing of toast on hover
                    style: {
                        background: "var(--color-red-500)",
                        borderRadius: "8px",
                        fontSize: "var(--text-body-s)"
                    }
                }).showToast();
            }
        });
    });

    const removeFromCarts = document.querySelectorAll(`[data-type=${removeFromCartType}]`);
    removeFromCarts.forEach(removeFromCart => {
        if (removeFromCart.dataset.script === 'loaded') return;
        removeFromCart.dataset.script = 'loaded';

        removeFromCart.addEventListener('submit', async (e) => {
            e.preventDefault();
            if (removeFromCart.dataset.loading === 'true')
                return;

            const formData = new URLSearchParams();
            formData.append('action', 'ajax_remove_from_cart');
            formData.append('security', ajax_remove_from_cart_object.nonce);
            const form = new FormData(removeFromCart);
            for (let [name, value] of form.entries()) {
                formData.append(name, value);
            }

            const productId = formData.get('product_id');
            const itemKey = formData.get('item_key');

            if (!productId) {
                console.error("You should set product_id input on 'remove-from-cart' form");
                return;
            }
            if (!itemKey) {
                console.error("You should set item_key input on 'remove-from-cart' form");
                return;
            }

            removeFromCart.dataset.loading = 'true';
            const response = await fetch(ajax_remove_from_cart_object.url, {
                method: "POST",
                body: formData,
                headers: {
                    'Content-Type': 'application/x-www-form-urlencoded',
                }
            });

            const data = await response.json();
            removeFromCart.dataset.loading = 'false';

            if (data.success) {
                Toastify({
                    text: 'محصول با موفقیت از سبد خرید شما حذف شد.',
                    duration: 3000,
                    gravity: "top", // `top` or `bottom`
                    position: "center", // `left`, `center` or `right`
                    stopOnFocus: true, // Prevents dismissing of toast on hover
                    style: {
                        background: "var(--color-green-500)",
                        borderRadius: "8px",
                        fontSize: "var(--text-body-s)"
                    }
                }).showToast();

                jQuery(document.body).trigger('wc_fragment_refresh');
            } else {
                Toastify({
                    text: data.data,
                    duration: 3000,
                    gravity: "top", // `top` or `bottom`
                    position: "center", // `left`, `center` or `right`
                    stopOnFocus: true, // Prevents dismissing of toast on hover
                    style: {
                        background: "var(--color-red-500)",
                        borderRadius: "8px",
                        fontSize: "var(--text-body-s)"
                    }
                }).showToast();
            }
        });
    });

    const updateCarts = document.querySelectorAll(`[data-type=${updateCartQuantityType}]`);
    updateCarts.forEach(updateCart => {
        if (updateCart.dataset.script === 'loaded') return;
        updateCart.dataset.script = 'loaded';

        const input = updateCart.querySelector("[name=quantity]");
        input.addEventListener('input', async (e) => {
            e.preventDefault();
            if (updateCart.dataset.loading === 'true')
                return;

            const formData = new URLSearchParams();
            formData.append('action', 'ajax_update_cart_quantity');
            formData.append('security', ajax_update_cart_quantity_object.nonce);
            const form = new FormData(updateCart);
            for (let [name, value] of form.entries()) {
                formData.append(name, value);
            }

            const productId = formData.get('product_id');
            const itemKey = formData.get('item_key');
            const quantity = formData.get('quantity');
            if (!productId) {
                console.error("You should set product_id input on 'update-cart-quantity' form");
                return;
            }
            if (!quantity) {
                console.error("You should set quantity input on 'update-cart-quantity' form");
                return;
            }
            if (!itemKey) {
                console.error("You should set item_key input on 'update-cart-quantity' form");
                return;
            }

            updateCart.dataset.loading = 'true';
            const response = await fetch(ajax_update_cart_quantity_object.url, {
                method: "POST",
                body: formData,
                headers: {
                    'Content-Type': 'application/x-www-form-urlencoded',
                }
            });

            const data = await response.json();
            updateCart.dataset.loading = 'false';

            if (data.success) {
                Toastify({
                    text: 'سبد خرید شما با موفقیت بروزرسانی شد.',
                    duration: 3000,
                    gravity: "top", // `top` or `bottom`
                    position: "center", // `left`, `center` or `right`
                    stopOnFocus: true, // Prevents dismissing of toast on hover
                    style: {
                        background: "var(--color-green-500)",
                        borderRadius: "8px",
                        fontSize: "var(--text-body-s)"
                    }
                }).showToast();

                jQuery(document.body).trigger('wc_fragment_refresh');
            } else {
                Toastify({
                    text: data.data,
                    duration: 3000,
                    gravity: "top", // `top` or `bottom`
                    position: "center", // `left`, `center` or `right`
                    stopOnFocus: true, // Prevents dismissing of toast on hover
                    style: {
                        background: "var(--color-red-500)",
                        borderRadius: "8px",
                        fontSize: "var(--text-body-s)"
                    }
                }).showToast();
            }
        });
    });


    const checkoutFormType = 'checkout-form';
    const checkoutButtonType = 'checkout-button';
    const checkoutWidgetType = 'cart-widget-checkout';

    const checkoutForm = document.querySelector(`[data-type='${checkoutFormType}']`);
    const checkoutButton = document.querySelector(`[data-type='${checkoutButtonType}']`);

    if (!checkoutForm || !checkoutButton)
        return;

    checkoutForm.addEventListener('submit', (e) => {
        e.preventDefault();
    });

    if (checkoutForm.dataset.script !== 'loaded') {
        checkoutForm.dataset.script = 'loaded';

        async function updateCartCustomerInfo() {
            let widget = checkoutForm.querySelector(`[data-type='${checkoutWidgetType}']`);

            const formData = new URLSearchParams();
            formData.append('action', 'ajax_update_cart_customer_info');
            formData.append('security', ajax_update_cart_customer_info_object.nonce);
            const form = new FormData(checkoutForm);
            for (let [name, value] of form.entries()) {
                formData.append(name, value);
            }

            if (widget) widget.dataset.loading = 'true';
            const response = await fetch(ajax_update_cart_customer_info_object.url, {
                method: "POST",
                body: formData,
                headers: {
                    'Content-Type': 'application/x-www-form-urlencoded',
                }
            });
            if (widget) widget.dataset.loading = 'false';
            const data = await response.json();

            if (data.success) {
                jQuery(document.body).trigger('wc_fragment_refresh');
            }
        }

        checkoutForm.querySelector(`[data-type=select-box][data-for=city-selector]`)?.addEventListener('input', async () => {
            await updateCartCustomerInfo();
        });
    }

    document.querySelector(`[data-type=shipping-method]`)?.addEventListener('select', async () => {
        await updateCartCustomerInfo();
    });

    checkoutButton.addEventListener('click', async () => {
        if (checkoutButton.dataset.loading === 'true')
            return;

        const hasError = checkoutForm.querySelector(`[data-error=true]`);

        if (hasError) {
            checkoutForm.dataset.error = 'true';
            return;
        }

        const formData = new URLSearchParams();
        const form = new FormData(checkoutForm);
        for (let [name, value] of form.entries()) {
            formData.append(name, value);
        }

        checkoutButton.dataset.loading = 'true';
        const response = await fetch(window.location.origin + '?wc-ajax=checkout', {
            method: "POST",
            body: formData,
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded',
            }
        });
        checkoutButton.dataset.loading = 'false';
        const data = await response.json();

        if (data.result === "success") {
            window.history.pushState(undefined, "", data.redirect);
            window.location.reload();
        } else {
            // TODO
        }
    });


    const checkoutCouponType = 'checkout-coupon';
    const checkoutCoupon = document.querySelector(`[data-type='${checkoutCouponType}']`);
    if (!checkoutCoupon) return;

    const checkoutCouponMessageBoxType = 'checkout-coupon-message-box';
    const checkoutCouponButtonApplyType = 'checkout-coupon-button-apply';
    const checkoutCouponButtonRemoveType = 'checkout-coupon-button-remove';
    const checkoutCouponMessageType = 'checkout-coupon-message';

    const checkoutCouponInput = checkoutCoupon.querySelector(`input`);
    const checkoutCouponButtonApply = checkoutCoupon.querySelector(`[data-type='${checkoutCouponButtonApplyType}']`);
    const checkoutCouponButtonRemove = checkoutCoupon.querySelector(`[data-type='${checkoutCouponButtonRemoveType}']`);
    const checkoutCouponMessageBox = document.querySelector(`[data-type='${checkoutCouponMessageBoxType}']`);
    const checkoutCouponMessage = checkoutCouponMessageBox?.querySelector(`[data-type='${checkoutCouponMessageType}']`);

    checkoutCouponButtonApply.addEventListener('click', async () => {
        if (checkoutCoupon.dataset.loading === 'true')
            return;

        const formData = new URLSearchParams();
        formData.append('action', 'ajax_apply_coupon');
        formData.append('security', ajax_apply_coupon_object.nonce);
        formData.append('coupon_code', checkoutCouponInput.value);

        checkoutCoupon.dataset.loading = 'true';
        const response = await fetch(ajax_apply_coupon_object.url, {
            method: "POST",
            body: formData,
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded',
            }
        });
        checkoutCoupon.dataset.loading = 'false';
        const data = await response.json();

        if (checkoutCouponMessageBox) {
            if (data.success) {
                if (checkoutCouponMessage) checkoutCouponMessage.innerText = "کد تخفیف با موفقیت اعمال شد.";
                checkoutCouponMessageBox.dataset.error = "false";
                jQuery(document.body).trigger('wc_fragment_refresh');
                checkoutCouponInput.readOnly = true;
                checkoutCoupon.dataset.apply = 'true';
            } else {
                if (checkoutCouponMessage) checkoutCouponMessage.innerText = data.data;
                checkoutCouponMessageBox.dataset.error = "true";
            }
        }
    });

    checkoutCouponButtonRemove.addEventListener('click', async () => {
        if (checkoutCoupon.dataset.loading === 'true')
            return;

        const formData = new URLSearchParams();
        formData.append('action', 'ajax_remove_coupon');
        formData.append('security', ajax_remove_coupon_object.nonce);
        formData.append('coupon_code', checkoutCouponInput.value);

        checkoutCoupon.dataset.loading = 'true';
        const response = await fetch(ajax_remove_coupon_object.url, {
            method: "POST",
            body: formData,
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded',
            }
        });
        checkoutCoupon.dataset.loading = 'false';
        const data = await response.json();

        if (checkoutCouponMessageBox) {
            if (data.success) {
                if (checkoutCouponMessage) checkoutCouponMessage.innerText = "";
                checkoutCouponMessageBox.dataset.error = "false";
                jQuery(document.body).trigger('wc_fragment_refresh');
                checkoutCouponInput.readOnly = false;
                checkoutCouponInput.value = "";
                checkoutCoupon.dataset.apply = 'false';
            } else {
                if (checkoutCouponMessage) checkoutCouponMessage.innerText = data.data;
                checkoutCouponMessageBox.dataset.error = "true";
            }
        }
    });
}

document.addEventListener('DOMContentLoaded', cartActions);

function setupQuantity() {

    const quantityType = 'quantity';
    const quantityPlusType = 'quantity-plus';
    const quantityMinusType = 'quantity-minus';
    const quantityRemoveType = 'quantity-remove';
    const quantityInputType = 'quantity-input';

    const quantities = document.querySelectorAll(`[data-type=${quantityType}]`);
    quantities.forEach(quantity => {
        if (quantity.dataset.script === 'loaded') return;
        quantity.dataset.script = 'loaded';

        const min = parseInt(quantity.dataset.min);
        const max = parseInt(quantity.dataset.max);

        const quantityPlus = quantity.querySelector(`[data-type=${quantityPlusType}]`);
        const quantityMinus = quantity.querySelector(`[data-type=${quantityMinusType}]`);
        const quantityRemove = quantity.querySelector(`[data-type=${quantityRemoveType}]`);
        const quantityInput = quantity.querySelector(`[data-type=${quantityInputType}]`);

        if (!quantityPlus || !quantityMinus || !quantityInput)
            return;

        const event = new Event('input', {
            bubbles: true,
            cancelable: true,
        });

        quantityInput.value = Math.max(parseInt(quantityInput.value), min);

        quantityPlus.addEventListener('click', (e) => {
            e.preventDefault();
            if (parseInt(quantityInput.value) < max) {
                quantityInput.value = parseInt(quantityInput.value) + 1;
                quantityInput.dispatchEvent(event);
            }
        });

        quantityMinus.addEventListener('click', (e) => {
            e.preventDefault();
            if (parseInt(quantityInput.value) > min) {
                quantityInput.value = parseInt(quantityInput.value) - 1;
                quantityInput.dispatchEvent(event);
            }
        });

        if (!quantityRemove)
            return;

        quantityRemove.addEventListener('click', (e) => {
            e.preventDefault();
            quantityInput.value = 0;
            quantityInput.dispatchEvent(event);
        });
    });
}


document.addEventListener('DOMContentLoaded', () => {
    const variationBoxType = "variation-box";
    const variationInputType = "variation-id";
    const selectBoxType = "select-box";
    const selectBoxItemType = "select-box-item";
    const variationInfoType = "variation-info";

    const variations = document.querySelectorAll(`[data-type=${variationBoxType}]`);
    variations.forEach(variation => {
        const info = variation.querySelector(`[data-type=${variationInfoType}]`);
        const parentInput = variation.querySelector(`[data-type=${variationInputType}]`);
        const selectVariationsIds = [];
        const selectBoxes = variation.querySelectorAll(`[data-type=${selectBoxType}]`);

        for (let i = 0; i < selectBoxes.length; i++) {
            const selectBox = selectBoxes[i];
            selectVariationsIds.push([]);
            const select = selectBox.querySelector(`select`);
            const items = selectBox.querySelectorAll(`[data-type=${selectBoxItemType}]`);

            select.selectedIndex = -1;

            select.addEventListener("select", () => {
                const itemIndex = select.selectedIndex;
                if (itemIndex < 0) selectVariationsIds[i] = [];
                else selectVariationsIds[i] = items[itemIndex].dataset.variationsIds.split(",");

                for (let j = 0; j < selectBoxes.length; j++) {
                    const selectBox = selectBoxes[j];
                    const items = selectBox.querySelectorAll(`[data-type=${selectBoxItemType}]`);
                    let variationsIds = [];

                    for (let k = 0; k < selectBoxes.length; k++) {
                        if (selectVariationsIds[k].length === 0 || k === j) continue;
                        if (variationsIds.length === 0) {
                            variationsIds = selectVariationsIds[k];
                            continue;
                        }
                        variationsIds = variationsIds.filter(value => selectVariationsIds[k].includes(value))
                    }

                    items.forEach(item => {
                        let disabled = true;
                        variationsIds.forEach(variationId => {
                            if (item.dataset.variationsIds.includes(variationId))
                                disabled = false;
                        });
                        if (disabled && variationsIds.length > 0) item.dataset.disabled = 'true';
                        else item.dataset.disabled = 'false';
                    });
                }

                let fill = true;
                for (let j = 0; j < selectBoxes.length; j++) {
                    const select = selectBoxes[j].querySelector(`select`);
                    if (select.selectedIndex < 0) fill = false;
                }
                if (fill) {
                    let variationsIds = [];
                    for (let j = 0; j < selectBoxes.length; j++) {
                        if (variationsIds.length === 0) {
                            variationsIds = selectVariationsIds[j];
                            continue;
                        }
                        variationsIds = variationsIds.filter(value => selectVariationsIds[j].includes(value))
                    }
                    parentInput.value = variationsIds[0];
                    const option = info.querySelector(`option[value='${parentInput.value}']`);
                    document.querySelector("[data-type='dialog-content-product-widget']").dataset.stock = option.dataset.stock;
                    document.querySelector("[data-type='stock-message']").innerText = option.dataset.stock === 'true' ? 'آماده ارسال' : 'ناموجود';
                    document.querySelector("[data-type='discount-box']").dataset.discount = option.dataset.discount;
                    document.querySelector("[data-type='discount']").innerText = `${option.dataset.discount}٪`;
                    document.querySelector("[data-type='regular-price']").innerText = `${option.dataset.regularPrice} تومانء`;
                    document.querySelector("[data-type='sale-price']").innerText = `${option.dataset.salePrice} تومانء`;
                }
            });
        }
    });
});