/**
 * ----------------------------------------------------------------------------
 * GXJS DonateButton
 * @module:   GX
 * @version:  1.2
 * @modified: 04/27/2023
 * @author    CN
 * ----------------------------------------------------------------------------
 */

'use strict';

let dnForm = ncf.makePageFragment(
    `
    <div class="donatebutton">

        <div class="donatebutton__container" data-elemid="formContainer">

            <div class="swiper__container is-hidden" data-elemid="formLoader">
                <div class="swiper__preload">
                    <div class="swiper__preload__animation">
                        <span></span>
                        <span></span>
                        <span></span>
                    </div>
                    <h3>One moment while we process your gift ...</h3>
                </div>
            </div>

            <div class="donatebutton__content" data-elemid="formContent">

                <div class="donatebutton__purpose-section">${buttonPurpose}</div>

                <div data-elemid="dneditor"></div>

                <div class="ncf-form__container">

                    <div class="ncf-form__section" data-elemid="payment-section">
                        <div class="ncf-form__payment-type-section ncf-form__sub-section">
                            <h3 class="ncf-form__step-label">1. Select a gift type</h3>
                            <div class="ncf-form__row">
                                <div class="ncf-form__field ncf-select ncf-select--payment-type" data-elemid="ptypeSelect"></div>
                                <span class="ncf-link js-modal" data-modal="aboutFees">(eCheck/credit card costs)</span>
                            </div>
                        </div>
                    </div>

                    <div class="ncf-form__section" data-elemid="address-section">
                        <h3 class="ncf-form__step-label" data-elemid="gift_title">2. Make a gift</h3>
                        <div class="ncf-form__sub-section ncf-form__amount-section" data-elemid="amount_section"></div>
                        ${ncf.gmBlock(true)}
                    </div>

                    <div class="ncf-form__section">

                        <div class="ncf-form__sub-section ncf-form__recurrence-section" data-elemid="additional-section">

                            <h3 class="ncf-form__step-label">3. Additional Information</h3>
                            <p class="ncf-form__label-text ncf-form__label-text--inline">How often would you like for this gift to occur?</p>

                            <div class="ncf-form__row">
                                <div class="ncf-form__field ncf-select ncf-select--recurrence" data-elemid="rTypeSelect"></div>
                            </div>

                            <div class="ncf-form__recurrence-container" data-elemid="recr_info"></div>

                            <div class="ncf-form__comments" data-elemid="commentWrapper">
                                <span>Comments (Optional)</span>
                                <div class="ncf-form__row">
                                    <div class="ncf-form__field ncf-form__field--additional-comments">
                                        <textarea class="ncf-field" placeholder="Instructions or comments about this gift" maxlength="255" data-elemid="comments"></textarea>
                                    </div>
                                </div>
                            </div>

                        </div>

                    </div>

                    <div class="ncf-form__footer section-toggle">
                        <h4 class="text-blue" data-elemid="gift_reminder">You're giving to ${fundName}.</h4>
                        <p>By clicking Give, you agree that you are making a nonrefundable gift exclusively for charitable purposes to the above mentioned fund, a component fund of National Christian Foundation (NCF), subject to NCF\'s full discretion and control.</p>
                    </div>

                    <div class="button-container" data-elemid="submit_section">
                        <div class="g-recaptcha" style="position: relative;"></div>
                        <button type="button" class="button button--primary" data-elemid="submitbutton"></button>
                    </div>

                </div>

            </div>

        </div>

    </div>
    `
);

dnForm.recr_info.hide();

let handlePaymentTypeChange = function() {
    if (paymentSelect.val() == 'cc') {
        dnForm.cc_info.show();
        dnForm.bk_info.hide();
        dnForm.gift_title.html('2. Make a credit card gift');
    } else if (paymentSelect.val() == 'bk') {
        dnForm.cc_info.hide();
        dnForm.bk_info.show();
        dnForm.gift_title.html('2. Make an eCheck gift');
    }
};

// When the gift amount or recurrence type is changed, update the gift reminder at the bottom of the page
let buildGiftReminder = function(updatedAmountText, recurrenceType) {

    let updatedAmount = updatedAmountText.replace(/,/g , '');

    let recurrenceText;

    if (recurrenceType == 'wk') {
        recurrenceText = ' weekly';
    } else if (recurrenceType == 'bw') {
        recurrenceText = ' bi-weekly';
    } else if (recurrenceType == 'mn') {
        recurrenceText = ' monthly';
    } else if (recurrenceType == 'qt') {
        recurrenceText = ' quarterly';
    } else if ( recurrenceType == 'yr') {
        recurrenceText = ' yearly';
    } else {
        recurrenceText = '';
    }

    let amountText = '';

    if (updatedAmount != '') {
        amountText = '$' + $.number(updatedAmount, 2);
    }

    dnForm.gift_reminder.html(`You're giving ${amountText} ${recurrenceText} to ${fundName}.`);
};

// This is to enforce maxlength on textarea in older browsers
dnForm.comments.bind('input propertychange', function() {
    var input = $( this ),
        maxLength = input.attr('maxlength'),
        value = input.val();

    if (value.length > maxLength) {
        input.val(value.substring(0, maxLength));
    }
});

var dnEditor = new skuid.ui.Editor(
        dnForm.dneditor,
        {
            showSaveCancel: false
        }
    ),
    fieldOptions = {};

// Merge in data, if we have it
var statePicklist = buildStatePicklist();

dnForm.stateWrapper.append(statePicklist);

var countryPicklist = buildCountryPicklist({
    required: true,
    selectedOption: 'United States Of America'
});

dnForm.countryWrapper.append(countryPicklist);

var salutationPicklist = buildSalutationPicklist();

dnForm.salutationPicklist.append(salutationPicklist);

// Validate phone number input
dnForm.phonenum.keypress(function(event) {
    if (event.which < 48 || event.which > 57 || $(this).val().length > 11) {
        event.preventDefault();
    }

    if ($(this).val().length == 3 || $(this).val().length == 7) {
        $(this).val($(this ).val() + '-' );
    }
});

// Phone type selection box
const phoneTypeOptions = [
    {
        value: 'Cell Phone',
        label: 'Cell'
    },
    {
        value: 'Home Phone',
        label: 'Home'
    },
    {
        value: 'Work Phone',
        label: 'Work'
    }
];

var phoneTypeSelect = skuid.ui.renderers.PICKLIST.edit({
    entries: phoneTypeOptions,
    required: true
});

dnForm.phoneTypeSelect.append(phoneTypeSelect);

// Main giving type selection box
var payOptions = [
    {
        value: 'bk',
        label: 'Bank Account'
    },
    {
        value: 'cc',
        label: 'Credit Card'
    }
];

var paymentSelect = skuid.ui.renderers.PICKLIST.edit({
    entries: payOptions,
    required: true
}).change(handlePaymentTypeChange);

dnForm.ptypeSelect.append(paymentSelect);

// Bank Account Types select
var baSelect = skuid.ui.renderers.PICKLIST.edit({
    entries: [
        {
            value: 'ck',
            label: 'Checking Account'
        },
        {
            value: 'sv',
            label: 'Savings'
        },
        {
            value: 'bc',
            label: 'Business Checking'
        }
    ],
    required: true
});

dnForm.baTypeSelect.append(baSelect);

var amountSign = $('<span class="amount-label">').text('$ '),
    amountInput = $('<input class="ncf-field">').prop('placeholder', 'Amount');

skuid.utils.delayInputCallback(amountInput, function(newAmount, oldAmount) {
    buildGiftReminder(newAmount, recurrenceSelect.val());
});

var amountField = $('<div class="ncf-form__field ncf-form__field--amount">').append(amountSign, amountInput);
var amountOutput = $('<div class="ncf-form__row">').append(amountField);

dnForm.amount_section.append(amountOutput);

// Month selection box for credit card expiration fields
var monthOptions = [{
    value: '',
    label: 'MM'
}];

for (var i = 1; i <= 12; i++) {
    if (i < 10) {
        monthOptions.push({
            value: '0' + i,
            label: '0' + i
        });
    } else {
        monthOptions.push({
            value: i,
            label: i
        });
    }
}

var monthSelect = skuid.ui.renderers.PICKLIST.edit({
    entries: monthOptions,
    required: true
});

var monthSelectWrapper = $('<div class="ncf-form__field ncf-select ncf-select--expiration-field">');

dnForm.monthSelectWrapper = monthSelectWrapper;
monthSelectWrapper.append( monthSelect );
dnForm.monthSelect = monthSelect;

//  Year selection box for credit card expiration fields
var yearOptions = [{
    value: '',
    label: 'YY'
}];

for ( var i = 0; i <= 8; i++ ) {
    var loopYear = new Date().getFullYear() + i;

    yearOptions.push({
        value: loopYear.toString().substring(2),
        label: loopYear.toString().substring(2)
    });
}

var yearSelect = skuid.ui.renderers.PICKLIST.edit({
    entries: yearOptions,
    required: true
});

var yearSelectWrapper = $('<div class="ncf-form__field ncf-select ncf-select--expiration-field">');

dnForm.yearSelectWrapper = yearSelectWrapper;
yearSelectWrapper.append(yearSelect);
dnForm.yearSelect = yearSelect;

dnForm.exp_box.append(monthSelectWrapper, yearSelectWrapper);

//  Recurrence options
var recurrenceSelect = skuid.ui.renderers.PICKLIST.edit({
    entries: ncf.recurrenceOptions,
    required: true
}).change( function() {
    buildGiftReminder( amountInput.val(), recurrenceSelect.val() );
    if ( recurrenceSelect.val() != 'ot' ) {
        dnForm.recr_info.show();
    } else {
        dnForm.recr_info.hide();
    }
});

dnForm.rTypeSelect.append(recurrenceSelect);

// Recurrence start date and length
var endDate = new Date();
endDate.setFullYear( endDate.getFullYear() + 3 );

var endDateMessage = $('<p class="text-red text-strong is-hidden">').text('Note: may not extend beyond three years');

var startLabel = $('<span class="ncf-form__inline-label">').text('From:');

var startDateBox = skuid.ui.renderers.DATE
    .edit({
        value: null
    })
    .prop('placeholder', 'Start Date')
    .addClass('ncf-field');

var endLabel = $('<span class="ncf-form__inline-label">').text('To:');

var endDateBox = skuid.ui.renderers.DATE
    .edit({
        value: null
    })
    .prop('placeholder', 'End Date')
    .addClass('ncf-field')
    .click( function() {
        endDateMessage.css({
            'display': 'inline-block'
        });
    });

startDateBox.datepicker('option', ncf.getStartDatePickerOptions(null, endDate, startDateBox, endDateBox));
endDateBox.datepicker('option', ncf.getEndDatePickerOptions(null, endDate, startDateBox, endDateBox));

var recrMessage = $('<div class="ncf-form__recurrence-message">').html(
    `
    <ul>
        <li>
            <p><span class="text-bold">Note:</span> Each gift in a recurring gift schedule may take up to two days to fully process. For example, a monthly schedule that is set for the 1st of each month may produce a completed gift on the 1st, 2nd, or 3rd of each month.</p>
        </li>
    </ul>
    `
);

var startDateOutput = $('<div class="ncf-form__field ncf-form__field--recurrence-date ncf-form__field--start">').append(startLabel, startDateBox),
    endDateOutput = $('<div class="ncf-form__field ncf-form__field--recurrence-date ncf-form__field--end">').append(endLabel, endDateBox),
    recurrenceRow = $('<div class="ncf-form__row">').append(startDateOutput, endDateOutput);

dnForm.recr_info.append(recurrenceRow, endDateMessage, recrMessage);

var spryValidations = [];
var ccSpryValidations = [];
var bankSpryValidations = [];

// Activate International State/Province
countryPicklist.on('change', function() {
    ncf.provinceCountry( countryPicklist.val() );

    if (countryPicklist.val() === 'United States Of America') {
        // Find and remove item from an array
        for (i = 0; i < spryValidations.length; i++) {
            if ( spryValidations[i].element.dataset.elemid === 'province') {
                spryValidations.splice( i, 1 );
            }
        }

        spryValidations.push(ncf.makeRequiredSelect(dnForm.stateWrapper));
    } else {
        // Find and remove item from an array
        for (i = 0; i < spryValidations.length; i++) {
            if (spryValidations[i].element.dataset.elemid === 'stateWrapper') {
                spryValidations.splice(i, 1);
            }
        }

        spryValidations.push(ncf.makeRequiredField(dnForm.province));
    }
});

$(document).ready( function() {
    countryPicklist.change();
});

spryValidations.push(ncf.makeRequiredCurrency(amountInput));
spryValidations.push(ncf.makeRequiredField(dnForm.firstName));
spryValidations.push(ncf.makeRequiredField(dnForm.lastName));
spryValidations.push(ncf.makeRequiredField(dnForm.address));
spryValidations.push(ncf.makeRequiredField(dnForm.city));
spryValidations.push(ncf.makeRequiredSelect(dnForm.countryWrapper));
spryValidations.push(ncf.makeRequiredZip(dnForm.zip));
spryValidations.push(ncf.makeRequiredEmail(dnForm.emailaddr));

dnForm.emailaddr.attr('name', 'email_address');

$(document).ready(function() {
    dnForm.emailaddr.after('<input type="text" name="email_address_confirm" class="ncf-field ncf-field-confirm" id="email_address_confirm" data-elemid="emailaddr_confirm" placeholder="Confirm Email Address *" />' );
});

ccSpryValidations.push(ncf.makeRequiredCreditCardNumber(dnForm.cc_number));
ccSpryValidations.push(ncf.makeRequiredSecurityCode(dnForm.cc_code));
ccSpryValidations.push(ncf.makeRequiredSelect(yearSelectWrapper));
ccSpryValidations.push(ncf.makeRequiredSelect(monthSelectWrapper));

bankSpryValidations.push(ncf.makeRequiredField(dnForm.bk_nameOnAccount));
bankSpryValidations.push(ncf.makeRequiredRoutingNumber(dnForm.bk_routingNumber));
bankSpryValidations.push(ncf.makeRequiredBankAccountNumber(dnForm.bk_accountNumber));

// Get the form elements to modify
const formTitle = document.getElementsByClassName('page-title')[0];

// Use dnform to run post DOM modification
const formContainer = dnForm.formContainer[0];
const formLoader = dnForm.formLoader[0];
const formContent = dnForm.formContent[0];

// Hide the donate form and show the loading animation on submission
const hideForm = () => {
    // Hide the form elements
    let formElements = [formContent, formTitle];
    formElements.forEach(elem => elem.classList.add('is-hidden'));

    // Show the loading animation
    formLoader.classList.remove('is-hidden');
    formLoader.classList.add('is-visible');
};

// Show the donate form and hide the loading animation on submission
const showForm = () => {
    // Hide the form elements
    let formElements = [formContent, formTitle];
    formElements.forEach(elem => elem.classList.remove('is-hidden'));

    // Show the loading animation
    formLoader.classList.add('is-hidden');
    formLoader.classList.remove('is-visible');
};

// Show the confirmation inline after it's completed loading
const loadConfirmationOutput = (fragments) => {

    // Hide the loading animation
    formLoader.classList.remove('is-visible');
    formLoader.classList.add('is-hidden');

    formTitle.innerHTML = '<h1 class="page-title__heading">Thank you!</h1>';
    formTitle.classList.remove('is-hidden');

    // Append the form submission details
    dnForm.formContainer.append(fragments);
}

// Form submission
let submitButton = new NCFButton({
    elem: dnForm.submitbutton,
    title: 'Give',
    action: function() {

        let useValidations = [];

        // reCaptcha site key
        const siteKey = '6LdJOdAZAAAAADafpiobf4iG_E2xNC04JJ1uX0EK';

        // Invoke reCaptcha
        grecaptcha.ready(function() {

            // Execute the captcha validation
            grecaptcha.execute(siteKey, {action: 'submit'}).then(function(recToken) {

                // Capture bots
                if ($('#email_address_confirm').val()) {

                    console.log('failure');
                    return false;

                } else {

                    if (paymentSelect.val() == 'cc' || paymentSelect.val() == 'bk') {
                        if (paymentSelect.val() == 'cc') {
                            useValidations = spryValidations.concat(ccSpryValidations);
                        } else if (paymentSelect.val() == 'bk') {
                            useValidations = spryValidations.concat(bankSpryValidations);
                        }
                    }

                    if (ncf.validateSpry(useValidations)) {

                        submitButton.processing();
                        let formErrs = [];

                        let formData = {
                            button: givingButtonID,
                            payment_type: paymentSelect.val(),
                            amount: amountInput.val().replace(/[^0-9.]/g,''),
                            salutation: salutationPicklist.val(),
                            first_name: dnForm.firstName.val(),
                            last_name: dnForm.lastName.val(),
                            address: dnForm.address.val(),
                            city: dnForm.city.val(),
                            state: countryPicklist.val() === 'United States Of America' ? statePicklist.val() : 'N/A',
                            province: countryPicklist.val() === 'United States Of America' ? null : dnForm.province.val(),
                            zip: dnForm.zip.val(),
                            country: countryPicklist.val(),
                            phone: dnForm.phonenum.val(),
                            phonetype: phoneTypeSelect.val(),
                            email: dnForm.emailaddr.val(),
                            recr_unit: recurrenceSelect.val(),
                            comments: dnForm.comments.val(),
                            source: window.location.href
                        };

                        // Amount is always required, and should always be greater than 0
                        if (formData.amount === '' || formData.amount <= 0) {
                            formErrs.push({
                                fieldName: 'Amount',
                                obj: amountInput
                            });
                        }

                        if (paymentSelect.val() === 'cc') {
                            $.extend(
                                formData, {
                                    cc_number: dnForm.cc_number.val(),
                                    cc_exp: monthSelect.val() + yearSelect.val(),
                                    cc_code: dnForm.cc_code.val()
                                }
                            );

                            ncf.validateCC(formData, yearSelect.val(), monthSelect.val());

                        } else if (paymentSelect.val() === 'bk') {
                            $.extend(
                                formData, {
                                    baType: baSelect.val(),
                                    bk_routingNumber: dnForm.bk_routingNumber.val(),
                                    bk_accountNumber: dnForm.bk_accountNumber.val(),
                                    bk_nameOnAccount: dnForm.bk_nameOnAccount.val()
                                }
                            );

                            ncf.validateBK(formData );
                        }

                        if (recurrenceSelect.val() !== 'ot') {
                            $.extend( formData, {
                                start_date: startDateBox.val(),
                                end_date: endDateBox.val()
                            });

                            if (formData.start_date === '') {
                                formErrs.push({
                                    fieldName: 'Recurring Start Date'
                                });
                            }

                            if (formData.end_date === '') {
                                formErrs.push({
                                    fieldName: 'Recurring End Date'
                                });
                            }

                            if (Date.parse(formData.start_date) >= Date.parse(formData.end_date)) {
                                formErrs.push({
                                    message: 'The End Date must be greater than the Start Date.'
                                });
                            }
                        }

                        //  Ifany required values are missing/invalid, halt and report the error(s)
                        if (formErrs.length > 0) {
                            submitButton.failure(true);
                            showFormErrors(dnEditor, formErrs);
                            return false;
                        } else {
                            hideForm();
                        }

                        let token = recToken;

                        GXDonateNowController.processGift(
                            JSON.stringify(formData),
                            token,
                            function(result, event) {
                                console.log(result);
                                if (result != null && result.bg != null) {
                                    submitButton.success();
                                    submitButton.elem.remove();

                                    // Show the confirmation output
                                    buildConfirmationOutput(result.bg);
                                } else {
                                    submitButton.failure(true);

                                    if (result != null && result.errs != null) {

                                        // Reshow the form on error
                                        showForm();

                                        let errStr = 'ERROR - ';

                                        $.each(result.errs, function(i, val) {
                                            errStr += (i + 1) + '. ' + val.text + ' ';
                                        });

                                        dnEditor.handleMessages([{
                                            severity: 'ERROR',
                                            message: errStr
                                        }]);
                                    }
                                }
                            }
                        );
                    }
                }
            });
        });
    }
});

handlePaymentTypeChange();

// Append the form to the form wrapper
$('#dnForm').append(dnForm.root);

// Construct the confirmation output
const buildConfirmationOutput = (data) => {

    if (!data) {
        return false;
    }

    const trans_id_column =
        `
        <div class="ncf-table__row">
            <div class="ncf-table__column">ID #:</div>
            <div class="ncf-table__column" data-elemid="transNum"></div>
        </div>
        `;

    const comments_column =
        `
        <div class="ncf-table__row">
            <div class="ncf-table__column">Comments:</div>
            <div class="ncf-table__column" data-elemid="comments"></div>
        </div>
        `;

    const giftSummary = ncf.makePageFragment(
        `
        <h3 class="ncf-form__step-label">We have received your gift.</h3>
        <p>The following is a summary of your gift details.</p>

        <div class="ncf-table ncf-table--confirm-detail no-border">

            <div class="ncf-table__row">
                <div class="ncf-table__column">Gift Description:</div>
                <div class="ncf-table__column" data-elemid="paymenttype"></div>
            </div>

            <div class="ncf-table__row">
                <div class="ncf-table__column">Date Submitted:</div>
                <div class="ncf-table__column" data-elemid="submitdate"></div>
            </div>

            <div class="ncf-table__row">
                <div class="ncf-table__column">Status:</div>
                <div class="ncf-table__column" data-elemid="status"></div>
            </div>

            <div class="ncf-table__row">
                <div class="ncf-table__column">Amount:</div>
                <div class="ncf-table__column" data-elemid="amount"></div>
            </div>

            <div class="ncf-table__row">
                <div class="ncf-table__column">Fund:</div>
                <div class="ncf-table__column" data-elemid="fund"></div>
            </div>

            <div class="ncf-table__row">
                <div class="ncf-table__column">Giver:</div>
                <div class="ncf-table__column" data-elemid="giver"></div>
            </div>

            <div class="ncf-table__row">
                <div class="ncf-table__column">Frequency:</div>
                <div class="ncf-table__column" data-elemid="frequency"></div>
            </div>

            <div class="ncf-table__row">
                <div class="ncf-table__column">Timing:</div>
                <div class="ncf-table__column" data-elemid="timing"></div>
            </div>

            ${data.AuthorizeNetId__c != null ? trans_id_column : ''}
            ${data.Comments__c != null ? comments_column : ''}

        </div>

        <div class="donatebutton__confirm-footer">
            <p>We have emailed you a PDF receipt for your records.</p>
            <div class="button-container">
                <button type="button" class="button button--primary" onclick="window.location.reload()">Make another donation</button>
            </div>
        </div>
        `
    );

    let tzoffset = new Date().getTimezoneOffset() * 60000;

    giftSummary.submitdate.text((new Date(data.CreatedDate)).toLocaleDateString());
    giftSummary.status.text(data.Status__c);
    giftSummary.fund.text(data.GivingButton__r.Fund__r.LongFundName__c);
    giftSummary.paymenttype.text(data.Payment_Type__c);

    giftSummary.amount.text('$' + ( !data.isRecurring__c
        ? $.number( data.Amount__c, 2)
        : $.number(data.Recurrence_Amount__c, 2)
    ));

    giftSummary.giver.text(data.Contact__r.Name);

    giftSummary.frequency.text(data.isRecurring__c
        ? 'Recurring gift'
        : 'One-time gift');

    giftSummary.timing.text(data.isRecurring__c
        ? data.Recurrence_Type__c + ' from ' + (new Date( data.Recurrence_Start_Date__c + tzoffset ) ).toLocaleDateString() + ' to ' + ( new Date(data.Recurrence_End_Date__c + tzoffset)).toLocaleDateString()
        : (new Date(data.Execution_Date__c + tzoffset)).toLocaleDateString());

    if (data.AuthorizeNetId__c != null) {
        giftSummary.transNum.text(data.AuthorizeNetId__c);
    }

    if (data.Comments__c != null) {
        giftSummary.comments.text(data.Comments__c);
    }

    // Output the form submission confirmation
    loadConfirmationOutput(giftSummary.root);
};

$(document).ready(function() {
    // Run the invoked modals
    $(document).on('click', '.js-modal', function() {
        const modalData = $(this).data('modal');
        modalDialogFn(modalData);
    });
});
