/**
 * FunnelKit Square - ACH Bank Transfer Handler
 *
 * Handles ACH bank transfer payments using Square's Web SDK.
 * ACH uses Plaid for bank account verification.
 *
 * Flow: User clicks Place Order -> Plaid modal opens -> On success, order processes
 *
 * @package FunnelKit_Square
 */

/* global Square, fkwcsq_ach_params */

(function($) {
    'use strict';

    let payments = null;
    let ach = null;
    let isProcessing = false;
    let isInitialized = false;
    let paymentRequestData = null;

    /**
     * Get the current cart total from payment request data
     *
     * @returns {string} Cart total amount
     */
    function getCartTotal() {
        if (paymentRequestData && paymentRequestData.total && paymentRequestData.total.amount) {
            return paymentRequestData.total.amount;
        }

        if (fkwcsq_ach_params.payment_request && fkwcsq_ach_params.payment_request.total) {
            return fkwcsq_ach_params.payment_request.total.amount;
        }

        return '0.00';
    }

    /**
     * Initialize ACH payment method
     */
    async function initializeACH() {
        const container = document.getElementById('fkwcsq-ach-container');

        if (!container) {
            return;
        }

        if (isInitialized && ach) {
            return;
        }

        if (typeof Square === 'undefined') {
            showError(fkwcsq_ach_params.i18n.error_generic);
            return;
        }

        try {
            if (!payments) {
                payments = await Square.payments(
                    fkwcsq_ach_params.application_id,
                    fkwcsq_ach_params.location_id
                );
            }

            ach = await payments.ach({
                redirectURI: fkwcsq_ach_params.redirect_url,
                transactionId: fkwcsq_ach_params.transaction_id
            });

            isInitialized = true;
            hideError();
            ach.addEventListener('ontokenization', handleTokenization);

        } catch (error) {
            if (error.message && error.message.includes('not supported')) {
                showError(fkwcsq_ach_params.i18n.not_supported);
            } else {
                showError(fkwcsq_ach_params.i18n.error_generic);
            }
        }
    }

    /**
     * Start ACH tokenization process (opens Plaid modal)
     *
     * @returns {Promise<boolean>} Whether tokenization was initiated
     */
    async function startACHTokenization() {
        if (isProcessing || !ach) {
            return false;
        }

        const accountHolderName = $('#fkwcsq_ach_account_holder').val().trim();

        if (!accountHolderName) {
            showError(fkwcsq_ach_params.i18n.account_holder + ' is required');
            $('#fkwcsq_ach_account_holder').focus();
            return false;
        }

        isProcessing = true;
        hideError();

        try {
            const result = await ach.tokenize({
                accountHolderName,
                intent: 'CHARGE',
                amount: getCartTotal(),
                currency: fkwcsq_ach_params.currency
            });

            if (!result) {
                return true;
            }

            if (result.status === 'OK') {
                $('#fkwcsq_ach_nonce').val(result.token);

                if (result.details && result.details.ach) {
                    const details = result.details.ach;
                    const accountInfo = details.bankName + ' ****' + details.accountNumberSuffix;
                    $('#fkwcsq_ach_account_details').val(accountInfo);
                    showSuccess('Bank account connected: ' + accountInfo);
                }

                isProcessing = false;

                setTimeout(function() {
                    $('form.checkout #place_order').trigger('click');
                }, 100);

                return true;

            } else if (result.status === 'Cancel') {
                isProcessing = false;
                return false;
            } else {
                const errorMessage = result.errors && result.errors[0]
                    ? result.errors[0].message
                    : fkwcsq_ach_params.i18n.error_generic;
                showError(errorMessage);
                isProcessing = false;
                return false;
            }

        } catch (error) {
            showError(error.message || fkwcsq_ach_params.i18n.error_generic);
            isProcessing = false;
            return false;
        }
    }

    /**
     * Handle tokenization event from Plaid
     *
     * @param {Object} event Tokenization event
     */
    function handleTokenization(event) {
        const { tokenResult, error } = event.detail;

        isProcessing = false;

        if (error) {
            showError(error.message || fkwcsq_ach_params.i18n.error_generic);
            return;
        }

        if (tokenResult && tokenResult.status === 'OK') {
            $('#fkwcsq_ach_nonce').val(tokenResult.token);

            if (tokenResult.details && tokenResult.details.ach) {
                const details = tokenResult.details.ach;
                const accountInfo = details.bankName + ' ****' + details.accountNumberSuffix;
                $('#fkwcsq_ach_account_details').val(accountInfo);
                showSuccess('Bank account connected: ' + accountInfo);
            }

            setTimeout(function() {
                $('form.checkout #place_order').trigger('click');
            }, 100);

        } else if (tokenResult && tokenResult.status !== 'Cancel') {
            const errorMessage = tokenResult?.errors?.[0]?.message || fkwcsq_ach_params.i18n.error_generic;
            showError(errorMessage);
        }
    }

    /**
     * Handle form submission - intercept to open Plaid modal
     *
     * @returns {boolean} Whether to proceed with form submission
     */
    function handleFormSubmit() {
        const selectedPayment = $('input[name="payment_method"]:checked').val();

        if (selectedPayment !== 'fkwcsq_ach') {
            return true;
        }

        const nonce = $('#fkwcsq_ach_nonce').val();
        if (nonce) {
            return true;
        }

        startACHTokenization();
        return false;
    }

    /**
     * Show error message
     *
     * @param {string} message Error message
     */
    function showError(message) {
        $('#fkwcsq-ach-error')
            .text(message)
            .css('display', 'block')
            .css('color', '#dc3545');
    }

    /**
     * Show success message
     *
     * @param {string} message Success message
     */
    function showSuccess(message) {
        $('#fkwcsq-ach-error')
            .text(message)
            .css('display', 'block')
            .css('color', '#28a745');
    }

    /**
     * Hide error message
     */
    function hideError() {
        $('#fkwcsq-ach-error').hide();
    }

    /**
     * Destroy ACH instance
     */
    async function destroyACH() {
        if (ach) {
            try {
                await ach.destroy();
            } catch (e) {
                // Silently handle
            }
            ach = null;
            isInitialized = false;
        }
    }

    /**
     * Handle payment method change
     */
    async function handlePaymentMethodChange() {
        const selectedPayment = $('input[name="payment_method"]:checked').val();

        if (selectedPayment === 'fkwcsq_ach') {
            if (ach) {
                await destroyACH();
            }
            initializeACH();
        }
    }

    /**
     * Initialize when document is ready
     */
    $(document).ready(function() {
        if (typeof fkwcsq_ach_params === 'undefined') {
            return;
        }

        const selectedPayment = $('input[name="payment_method"]:checked').val();
        if (selectedPayment === 'fkwcsq_ach') {
            initializeACH();
        }

        $(document.body).on('change', 'input[name="payment_method"]', handlePaymentMethodChange);
        $('form.checkout').on('checkout_place_order_fkwcsq_ach', handleFormSubmit);

        // Handle FunnelKit checkout initialization
        $(document.body).on('init_checkout', async function() {
            const selectedPayment = $('input[name="payment_method"]:checked').val();
            if (selectedPayment === 'fkwcsq_ach') {
                initializeACH();
            }
        });

        $(document.body).on('updated_checkout', async function(_e, data) {
            if (data && data.fragments && data.fragments.fkwcsq_payment_request) {
                paymentRequestData = data.fragments.fkwcsq_payment_request;
            }

            const selectedPayment = $('input[name="payment_method"]:checked').val();
            if (selectedPayment === 'fkwcsq_ach') {
                await destroyACH();
                initializeACH();
            }
        });
    });

    $(window).on('unload', destroyACH);

})(jQuery);
