let flowClicked = false;

function handleChurnSolutionRewriteCancelButton($) {
    var elements = $('a[href*="levelstocancel"], a.woocommerce-button.cancel');
    if (elements.length > 0) {
        elements.each(function () {
            var element = $(this);
            element.on('click', blockDefaultCancellation)
        });
        checkConnection($, elements);
    }
}

function checkConnection($, elements) {
    $.ajax({
        url: `${churn_ajax_obj.base_url}/wp-json/churnsolution/v1/connection`,
        type: 'GET',
        dataType: 'json',
        beforeSend: function (xhr) {
            xhr.setRequestHeader('X-WP-Nonce', churn_ajax_obj.nonce);
        },
        success: function (response) {
            if (response?.app_id && response?.api_key) {
                const {app_id, api_key} = response;
                clickFlow($, elements, app_id, api_key);
            } else {
                console.error("Response does not contain appId or secretKey");
            }
        },
        error: function (jqXHR, textStatus, errorThrown) {
            console.error(jqXHR);
            elements.each(function () {
                var element = $(this);
                var href = element.attr('href');
                if (href?.includes('subscription_id')) {
                    element.addClass("wcs_block_ui_on_click");
                }
            });
        },
        complete: function () {
            elements.each(function () {
                var element = $(this);
                element.off('click', blockDefaultCancellation);
            });
        }
    });
}

function clickFlow($, elements, appId, secretKey) {
    elements.each(function () {
        var element = $(this);
        var href = element.attr('href'); // Get the href attribute

        if (href && !href?.includes('levelstocancel') && !href?.includes('subscription_id')) {
            return;
        }

        var tagName = element.prop("tagName").toLowerCase();
        element.on('click', function (e) {
            e.preventDefault();
            if (tagName === 'a') {
                const clickedUrl = this.getAttribute("href");
                const urlParams = new URLSearchParams(e.target.search);
                const levelstocancel = urlParams.get('levelstocancel');
                const subscriptionId = urlParams.get('subscription_id');
                const query = getRequestQuery({
                    levelId: levelstocancel,
                    subscriptionId,
                })
                element.removeClass("wcs_block_ui_on_click");
                if (query) {
                    if (flowClicked) return;
                    flowClicked = true;
                    checkSubscription($, query, appId, secretKey, clickedUrl, {
                        success: triggerChurnSolutionFlow,
                        error: () => { flowClicked = false },
                    }, $(this));
                } else {
                    console.error("There is no level value to cancel");
                }
            }
        });
    });
}

function checkSubscription($, query, appId, secretKey, clickedUrl, callback, clickedElement) {
    $.ajax({
        url: `${churn_ajax_obj.base_url}/wp-json/churnsolution/v1/subscription/${query}`,
        type: 'GET',
        dataType: 'json',
        beforeSend: function (xhr) {
            xhr.setRequestHeader('X-WP-Nonce', churn_ajax_obj.nonce);
        },
        success: function (response) {
            if (response?.external_id && response?.status !== 'cancelled') {
                callback.success && callback.success($, response, query, appId, secretKey, clickedElement);
            } else {
                console.error("Response does not contain subscription Id");
                if (clickedUrl) {
                    window.location.href = clickedUrl;
                }
            }
        },
        error: function (jqXHR, textStatus, errorThrown) {
            console.error(jqXHR);
            callback.error && callback.error(jqXHR, textStatus, errorThrown);
        },
        complete: function (jqXHR, textStatus) {
            callback.complete && callback.complete(jqXHR, textStatus);
        }
    });
}

function triggerChurnSolutionFlow($, subscription, query, appId, secretKey) {
    const subscriptionId = subscription.external_id;
    $.ajax({
        url: churn_ajax_obj.ajax_url,
        type: 'POST',
        data: {
            action: 'get_hmac_hash',
            nonce: churn_ajax_obj.nonce,
            subscription_id: subscriptionId,
            secret_key: secretKey
        },
        beforeSend: function (xhr) {
            xhr.setRequestHeader('X-WP-Nonce', churn_ajax_obj.nonce);
        },
        success: function (response) {
            window.churnSolution?.run(
                response,
                subscriptionId,
                appId,
                {
                    ...getChurnSolutionCallbacks($, query),
                    customTexts: {
                        'Back': 'Go Back',
                        'Next': 'Next Step',
                        'Decline Offer': 'No, cancel',
                        'Done': 'Finish',
                        'Cancel': 'Cancel',
                        'Cancel Subscription': 'Confirm Cancel',
                        'Close': 'Close Cancel',
                    }
                }
            );
        },
        error: function (xhr, status, error) {
            console.error(xhr.responseText);
        }
    });
}

function getChurnSolutionCallbacks($, query) {
    return {
        handleCancel: async () => {
            await new Promise((resolve, reject) => {
                handleSubscriptionCancel($, query, resolve, reject);
            });
        },
        handleClose: () => {
            flowClicked = false;
        },
        handleDone: () => {
            flowClicked = false;
            syncSubscription($, () => {
                location.reload();
            });
        },
        handleAbandon: () => {
            churnSolution.clearState();
        },
        handlePause: async ({pausePeriod}, customer) => {
            // await new Promise((resolve, reject) => {
            //     handlePaidMembershipProPause($, query, pausePeriod, resolve, reject);
            // });
        },
        handleSwitchPlan: () => {
        },
        handleTrialExtension: async ({trialExtensionDays}, customer) => {
            // await new Promise((resolve, reject) => {
            //     handlePaidMembershipProExtend($, query, trialExtensionDays, resolve, reject);
            // });
        },
        handleCoupon: async ({code}, customer) => {
            // await new Promise((resolve, reject) => {
            //     handlePaidMembershipProApplyCoupon($, query, code, resolve, reject);
            // });
        },
        autoCancel: false,
        autoPause: true,
        autoSwitchPlan: true,
        autoTrialExtension: true,
        autoCoupon: true
    };
}

function handleSubscriptionCancel($, query, resolve, reject) {
    $.ajax({
        url: `${churn_ajax_obj.base_url}/wp-json/churnsolution/v1/subscription/cancel/${query}`,
        type: 'POST',
        data: {},
        beforeSend: function (xhr) {
            xhr.setRequestHeader('X-WP-Nonce', churn_ajax_obj.nonce);
        },
        success: function (response, textStatus, xhr) {
            if (resolve) {
                resolve({message: ''});
            }
        },
        error: function (xhr, status, error) {
            console.error(xhr);
            if (xhr.status === 200 && xhr.responseText === "" && resolve) {
                resolve({message: ''});
            } else {
                if (reject) {
                    reject({message: 'Failed to cancel. Please contact support.'});
                }
            }
        }
    });
}

function handlePaidMembershipProApplyCoupon($, query, code, resolve, reject) {
    $.ajax({
        url: `${churn_ajax_obj.base_url}/wp-json/churnsolution/v1/subscription/apply-coupon/${query}`,
        type: 'POST',
        data: {
            coupon_code: code
        },
        beforeSend: function (xhr) {
            xhr.setRequestHeader('X-WP-Nonce', churn_ajax_obj.nonce);
        },
        success: function (response, textStatus, xhr) {
            if (resolve) {
                resolve({message: ''});
            }
        },
        error: function (xhr, status, error) {
            console.error(xhr);
            if (xhr.status === 200 && xhr.responseText === "" && resolve) {
                resolve({message: ''});
            } else {
                if (reject) {
                    reject({message: 'Failed to apply coupon. Please contact support.'});
                }
            }
        }
    });
}

function handlePaidMembershipProPause($, query, pausePeriod, resolve, reject) {
    $.ajax({
        url: `${churn_ajax_obj.base_url}/wp-json/churnsolution/v1/subscription/pause/${query}`,
        type: 'POST',
        data: {
            number_of_months: pausePeriod
        },
        beforeSend: function (xhr) {
            xhr.setRequestHeader('X-WP-Nonce', churn_ajax_obj.nonce);
        },
        success: function (response, textStatus, xhr) {
            if (resolve) {
                resolve({message: ''});
            }
        },
        error: function (xhr, status, error) {
            console.error(xhr);
            if (xhr.status === 200 && xhr.responseText === "" && resolve) {
                resolve({message: ''});
            } else {
                if (reject) {
                    reject({message: 'Failed to apply coupon. Please contact support.'});
                }
            }
        }
    });
}

function handlePaidMembershipProExtend($, query, trialExtensionDays, resolve, reject) {
    $.ajax({
        url: `${churn_ajax_obj.base_url}/wp-json/churnsolution/v1/subscription/extend-free-trial/${query}`,
        type: 'POST',
        data: {
            number_of_days: trialExtensionDays
        },
        beforeSend: function (xhr) {
            xhr.setRequestHeader('X-WP-Nonce', churn_ajax_obj.nonce);
        },
        success: function (response, textStatus, xhr) {
            if (resolve) {
                resolve({message: ''});
            }
        },
        error: function (xhr, status, error) {
            console.error(xhr);
            if (xhr.status === 200 && xhr.responseText === "" && resolve) {
                resolve({message: ''});
            } else {
                if (reject) {
                    reject({message: 'Failed to apply coupon. Please contact support.'});
                }
            }
        }
    });
}

function syncSubscription($, resolve) {
    return $.ajax({
        url: `${churn_ajax_obj.base_url}/wp-json/churnsolution/v1/subscription/sync-subscription`,
        type: 'POST',
        data: {},
        beforeSend: function (xhr) {
            xhr.setRequestHeader('X-WP-Nonce', churn_ajax_obj.nonce);
        },
        success: function (response, textStatus, xhr) {
            if (resolve) {
                resolve();
            }
        },
        error: function (xhr, status, error) {
            console.error(xhr);
        }
    });
}

function handleUpcomingInvoice($) {
    $('div[id*=pmpro_account-membership-]').each(function () {

        const cancelLink = $(this).find('a[href*="levelstocancel"]');

        if (cancelLink.length) {
            const urlParams = new URLSearchParams(new URL(cancelLink.attr('href')).search);
            const levelToCancel = urlParams.get('levelstocancel');
            const query = getRequestQuery({ levelId: levelToCancel });
            checkSubscription($, query, '', '', null, {success: replaceUpcomingInvoiceAndNextPaymentDate}, $(this));
        }
    });
}

function replaceUpcomingInvoiceAndNextPaymentDate($, subscription, query, appId, secretKey, el) {
    const upcomingAmount = subscription?.upcoming_invoice?.amount_due;
    const upcomingAmountBeforeTaxes = subscription?.upcoming_invoice?.total_excluding_tax;
    const tax = subscription?.upcoming_invoice?.tax;
    const totalDiscounts = subscription?.upcoming_invoice?.total_discounts;
    const pauseCollection = subscription?.pause_collection;
    const currencySymbol = subscription?.upcoming_invoice?.currency_symbol;
    if (el && upcomingAmount >= 0) {
        const itemLabels = el.find(".pmpro_list_item_label");
        itemLabels.each(function () {
            const itemLabel = $(this);

            if (itemLabel.text() == "Subscription") {
                const itemValue = itemLabel.siblings(".pmpro_list_item_value");
                const valueText = itemValue.text();
                const valueTextMatch = valueText.match(/\d+(\.\d+)?/);

                if (valueTextMatch) {
                    const originalAmount = parseFloat(valueTextMatch[0]);
                    const newAmount = parseFloat((parseFloat(upcomingAmount)).toFixed(2));
                    const newAmountBeforeTaxes = parseFloat((parseFloat(upcomingAmountBeforeTaxes)).toFixed(2));

                    const isDiscounted = Boolean(totalDiscounts);
                    const isTaxed = Boolean(tax);
                    const isSameFinalPrice = originalAmount === newAmount;

                    if (!isSameFinalPrice && ((isDiscounted && newAmount < originalAmount) || isTaxed )) {
                        let textTemplate = `${originalAmount.toFixed(2)}`;

                        if(isDiscounted){
                            textTemplate = `<s>${textTemplate}</s>`;
                        }

                        if (isDiscounted) {
                            textTemplate +=
                                `<div></div><strong>${currencySymbol}${newAmountBeforeTaxes}</strong> <span class="chr-sub-price-detail">after discount</span><div></div>`;
                        }

                        if (isTaxed) {
                            textTemplate += `<div></div><strong>${currencySymbol}${newAmount} <span class="chr-sub-price-detail">after taxes</span></strong><div></div>`;
                        }

                        const updatedText = valueText.replace(valueTextMatch[0], textTemplate);

                        itemValue.html(updatedText);
                    }else if(!isSameFinalPrice){
                        let textTemplate = `<strong>${newAmount}</strong>`;
                        const updatedText = valueText.replace(valueTextMatch[0], textTemplate);

                        itemValue.html(updatedText);
                    }
                }

            } else if (pauseCollection?.resumes_at && itemLabel.text() == "Next payment on") {
                const itemValue = itemLabel.siblings(".pmpro_list_item_value");
                const valueText = itemValue.text();

                if (valueText && pauseCollection?.resumes_at) {
                    itemLabel.html("Paused until");
                    itemValue.html(formatTimestamp(pauseCollection.resumes_at));
                }
            }
        });

    }
}

function formatTimestamp(seconds) {
    const date = new Date(seconds * 1000); // Convert seconds to milliseconds
    return date.toLocaleDateString('en-US', {month: 'long', day: 'numeric', year: 'numeric'});
}

function getRequestQuery(params = { levelId: null, subscriptionId: null }) {
    Object.keys(params).forEach((key) => {
        if (params[key] === null) {
            delete params[key];
        }
    });
    let query = "";
    if (params.levelId) {
        query = `?level_id=${params.levelId}`
    } else if (params.subscriptionId) {
        query = `?subscription_id=${String(params.subscriptionId)}`
    }
    return query;
}

function blockDefaultCancellation(e) {
    e.preventDefault();
    e.target.classList.remove("wcs_block_ui_on_click");
}

jQuery(document).ready(function ($) {
    // Call the custom JavaScript function
    handleChurnSolutionRewriteCancelButton($);
    // Call the update invoice logic
    handleUpcomingInvoice($);

});
