window.W2PShopCommon = new function () {

    // mm → inches
    function mmToIn(mm) {
        return mm / 25.4;
    }

    // inches → mm
    function inToMm(inches) {
        return inches * 25.4;
    }

    this.send_ajax_request = function(endpoint, data, headers, callback) {
        if (typeof endpoint === 'undefined') {
            if (typeof callback === 'function') {
                callback();
            }
            return;
        }

        if ( typeof data === 'undefined' ) { data = {}; }
        if ( typeof headers === 'undefined' ) { headers = {}; }

        let post_type = (Object.keys(data).length > 0) ? 'POST' : 'GET';
        jQuery.ajax({
            type: post_type,
            dataType: "json",
            url: endpoint,
            headers: headers,
            data: data,
            success: function (response, status, xhr, $form) {
                if (typeof callback === 'function') {
                    callback(response);
                }
            },
            error: function (xhr, status, error) {
                console.error('AJAX error:', { xhr: xhr, status: status, error: error, responseText: xhr.responseText });
                // Try to parse response if it's JSON
                let errorResponse = { success: false, data: { message: 'Request failed: ' + error } };
                try {
                    const parsedResponse = JSON.parse(xhr.responseText);
                    if (parsedResponse && parsedResponse.data && parsedResponse.data.message) {
                        errorResponse.data.message = parsedResponse.data.message;
                    }
                } catch (e) {
                    // Not JSON, use generic message
                }
                if (typeof callback === 'function') {
                    callback(errorResponse);
                }
            }
        });
    };

    this.utf8_to_b64 = function( str ) {
        return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g,
            function toSolidBytes(match, p1) {
                return String.fromCharCode('0x' + p1);
            })
        );
    };

    this.b64_to_utf8 = function(str) {
        // Decode the Base64 string into a binary string.
        let decoded_str = atob(str);
        try {
            // Attempt to decode the URI component if the decoded string was encoded.
            return decodeURIComponent(decodedStr.split('').map(function(c) {
                // Convert each character to its percent-encoded form.
                return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
            }).join(''));
        } catch (e) {
            // If there's an error in decoding (e.g., malformed URI sequence), return the decoded binary string as is.
            return decoded_str;
        }
    };

    this.display_success_message = function(title, message, callback) {
        this.display_message('success', title, message, callback);
    };

    this.display_error_message = function (title, message, callback) {
        this.display_message('error', title, message, callback);
    };

    this.display_remove_message = function(callback) {
        this.display_confirm_message('Are you sure?',
            "You won't be able to revert this!",
            'Yes, delete it!',
            callback
        );
    };

    this.display_cancel_message = function(callback) {
        this.display_confirm_message(
            'Are you sure?',
            "Your design will not be saved",
            'Yes, I am sure!',
            callback
        );
    };

    this.display_confirm_message = function(title, message, confirm_button_text, callback) {
        Swal.fire({
            title: title,
            text: message,
            icon: 'warning',
            showCancelButton: true,
            confirmButtonText: confirm_button_text
        }).then((result) => {
            if (result.isConfirmed) {
                if (typeof callback === 'function') {
                    callback();
                }
            }
        })
    };

    this.display_loading_dialog = function(title, message) {
        title = title || 'Loading';
        message = message || 'Please Wait ...';
        Swal.fire({
            title: title,
            html: message,
            allowOutsideClick: false,
            didOpen: () => {
                Swal.showLoading();
            }
        });
    };

    this.close_loading_dialog = function() {
        Swal.close();
    };

    this.update_confirm_message = function(title, message, confirm_button_text, cancel_button_text, reverse_buttons = false) {
        let updateConfig = {
            title: title || undefined,
            html: /<[^>]+>/.test(message) ? message : null,
            text: /<[^>]+>/.test(message) ? null : message,
            confirmButtonText: confirm_button_text || undefined,
            cancelButtonText: cancel_button_text || undefined,
            reverseButtons: reverse_buttons
        };

        Swal.update(updateConfig);
    };

    this.display_message = function(icon, title, message, callback) {
        Swal.fire({
            icon: icon,
            title: title,
            text: message
        }).then((result) => {
            if (typeof callback === 'function') {
                callback();
            }
        });
    };

    this.set_cookie = function(name, value, days) {
        let expires = "";
        if (days) {
            var date = new Date();
            date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
            expires = "; expires=" + date.toUTCString();
        }
        document.cookie = name + "=" + (value || "") + expires + "; path=/";
    };

    this.delete_cookie = function(name) {
        this.set_cookie(name, "", -1);
    };


    this.duplicateCartDesign = function(e) {
        var cartItemKey = jQuery(e).attr("data-cart-item-key");
        var designKey = jQuery(e).attr("data-design-key");
        var pdfDesignKey = jQuery(e).attr("data-pdf-design-key");
        var cart_design_type = "";
        if ( typeof designKey !== "undefined" ) {
            cart_design_type = "udraw";
        } else if ( typeof pdfDesignKey !== "undefined" ) {
            cart_design_type = "pdf";
        }

        W2PShopCommon.send_ajax_request(w2pshop_common_data.ajaxurl, {
            action: "w2pshop_duplicate_cart_design",
            design_key: designKey,
            customer_cart_item_key: cartItemKey,
            cart_design_type: cart_design_type,
            security: w2pshop_nonce[0]
        }, {}, function (response) {
            if (response.success === true) {
                location.reload();
            }
        });
    }

    this.deleteSavedDesign = function(e) {
        var savedDesignKey = jQuery(e).attr("data-saved-design-key");

        if (!savedDesignKey) {
            W2PShopCommon.display_error_message('Error', 'Invalid design key.', function() {});
            return;
        }

        if (typeof w2pshop_saved_data_nonce === 'undefined') {
            W2PShopCommon.display_error_message('Error', 'Security nonce is missing. Please refresh the page.', function() {});
            return;
        }

        W2PShopCommon.display_confirm_message(
            'Delete Design?',
            'Are you sure you want to delete this saved design? This action cannot be undone.',
            'Yes, delete it!',
            function() {
                W2PShopCommon.send_ajax_request(w2pshop_common_data.ajaxurl, {
                    action: "w2pshop_delete_saved_design",
                    saved_key: savedDesignKey,
                    security: w2pshop_saved_data_nonce[0]
                }, {}, function (response) {
                    if (response.success === true) {
                        W2PShopCommon.display_success_message('Deleted!', 'Your design has been deleted successfully.', function() {
                            location.reload();
                        });
                    } else {
                        var errorMessage = response.message || 'Failed to delete design. Please try again.';
                        W2PShopCommon.display_error_message('Error', errorMessage, function() {});
                    }
                });
            }
        );
    }
}

