import {updateOrderSummary} from './order-summary';
import {callAction} from '../utils/http-action';
import {retryAction, retryHelpers} from "./retry-action";
import {showValidationErrors} from '../utils/validation'
import {updateKlarnaPlacements} from '../basket/klarna';
import {getCSRFToken, CSRF} from "./csrf";
import {ROUTES} from '../utils/routes';

const voucherEl = {
    $basketVoucher: $('.checkout-voucher'),
    discountValue: '.checkout-widget__detail-value',
    orderTotalValue: '.checkout-widget__total-value',
    value: '.checkout-widget__item-value',
    formInvalid: 'form_invalid',
    fieldRow: '.form-row[data-row-required]',
    rowValidationError: 'form-row_validation-error',
    voucherHide: '.checkout-voucher-hide',
    fieldError: '.form-row__error',
    subtotal: '.checkout-widget__item-bold',
    vat: '.checkout-widget__item-vat',
    cc: '.checkout-widget__item-cc',
    delivery: '.checkout-widget__item-delivery',
    charity: '.checkout-widget__item-charity',
    discountItem: '.checkout-widget__details-discount',
    orderTotal: '.checkout-widget__total',
    voucher: '.checkout-voucher',
    voucherBtn: '.voucher__btn',
    voucherApplied: 'voucher-applied',
};

export function checkVoucherCode(e, current) {
    e && e.preventDefault()
    const context = current ? $(current).closest(voucherEl.voucher) : $(this).closest(voucherEl.voucher),
        value = context.find('input').val().trim(),
        encodedValue = encodeURIComponent(value),
        errorMsg = {
            status: 400,
            responseJSON: {
                globalMessage: {
                    message: 'Please enter a voucher code',
                }
            }
        };

    if (value && value.length) {
        executionVoucherApplying(encodedValue, context);
    } else {
        notApplyVoucher(errorMsg, context);
    }
}

function executionVoucherApplying(value, context) {
    const voucherButton = context.find(voucherEl.voucherBtn);
    voucherButton.attr('disabled', true);

    if (!Wick.checkLocalEnv) {
        const payload = {
            url: `${ROUTES.VOUCHER_UPDATE}/${value}`,
            type: 'POST',
            headers: {
                'CSRFToken': CSRF.getToken(),
            },
            retryLimit: retryHelpers.retryLimit,
            error: notApplyVoucher,
        };
        callAction(payload, applyVoucher, context);
    } else {
        //local usage
        if (Wick.BasketData.validPostCodes().includes(value)) {
            applyVoucher(Wick.BasketData.successVoucherData, context);
        } else {
            notApplyVoucher(Wick.BasketData.failVoucherData, context);
        }
    }
}

export function voucherRemove() {
    let voucher = $(this).parent(),
        voucherCode = voucher.attr('data-coupon-code');
    voucher.addClass('checkout-widget__voucher-removed').text('Voucher removed');
    voucherRemoveAction(voucherCode, voucher)
}

function voucherRemoveAction(code) {
    let encodedValue = encodeURIComponent(code);
    if (!Wick.checkLocalEnv) {
        const payload = {
            url: `${ROUTES.VOUCHER_UPDATE}/${encodedValue}`,
            type: 'DELETE',
            headers: {
                'Content-Type': 'application/json',
                'CSRFToken': CSRF.getToken(),
            },
            error: handleVoucherRemovingError,
        };
        callAction(payload, executionVoucherRemoving, code);
    } else {
        //local usage
        executionVoucherRemoving(Wick.BasketData.successVoucherData);
    }
}

function formattedTotalPriceWithoutSymbol(val) {
    return val.replace(/[$€£]/g, '');
}

function executionVoucherRemoving(data) {
    updateOrderSummary(
        data,
        getEqualMapForVoucherUpdate(data),
        true
    );
    updateKlarnaPlacements(formattedTotalPriceWithoutSymbol(data.total));
}

function applyVoucher(data, context) {
    const $voucherForm = context.find('form'),
        $voucherFormInput = context.find('input'),
        voucherButton = context.find(voucherEl.voucherBtn);

    clearValidationErrors($voucherForm);
    voucherEl.$basketVoucher.toggle(voucherEl.voucherHide);
    updateOrderSummary(
        data,
        getEqualMapForVoucherUpdate(data),
        true
    );
    updateKlarnaPlacements(formattedTotalPriceWithoutSymbol(data.total));
    setTimeout(function () {
        voucherButton.attr('disabled', false);
        $voucherFormInput.val('');
        voucherEl.$basketVoucher.toggle(voucherEl.voucherHide);
    }, 5000)
}

function notApplyVoucher(xhr, context) {
    const $voucherForm = context.find('form'),
        voucherButton = context.find(voucherEl.voucherBtn);

    if (xhr.status === 400) {
        showValidationErrors($voucherForm, xhr.responseJSON.globalMessage.message);
    }
    if (xhr.status === 401) {
        checkVoucherCode(...Array(1), $voucherForm);
    }
    if (xhr.status === 403) {
        retryVoucherAction($voucherForm);
    }

    voucherButton.attr('disabled', false);
}

function retryVoucherAction(voucherForm) {
    return new Promise((resolve) => {
        getCSRFToken(resolve);
    }).then(() => {
        retryAction(checkVoucherCode, retryHelpers.retryLimit, ...Array(1), voucherForm)
    }).catch(() => {
        showDefaultError();
    })
}

function retryVoucherRemoving(code) {
    return new Promise((resolve) => {
        getCSRFToken(resolve);
    }).then(() => {
        retryAction(voucherRemoveAction, retryHelpers.retryLimit, code);
    }).catch(() => {
        console.log('remove failed');
    })
}

function handleVoucherRemovingError(xhr, code) {
    if (xhr.status === 403) {
        retryVoucherRemoving(code);
    }
}

function showDefaultError(error = retryHelpers.errorMsg) {
    const voucher = getNotAppliedVoucher()
    showValidationErrors(voucher.find('form'), error);
}

function getNotAppliedVoucher() {
    if (!$(voucherEl.voucher).hasClass(voucherEl.voucherApplied)) {
        return $(voucherEl.voucher);
    }
}

function clearValidationErrors(form) {
    var $form = $(form);
    if ($form.hasClass(voucherEl.formInvalid)) {
        $form.removeClass(voucherEl.formInvalid)
            .find(voucherEl.fieldRow).removeClass(voucherEl.rowValidationError)
            .find(voucherEl.fieldError).remove();
    }
}

function getEqualMapForVoucherUpdate(data) {
    return [
        {
            item: voucherEl.subtotal,
            itemValue: voucherEl.value,
            dataValue: data.subTotal,
            title: 'Items subtotal:'

        },
        {
            item: voucherEl.vat,
            itemValue: voucherEl.value,
            dataValue: data.vat,
            title: 'VAT:'
        },
        {
            item: voucherEl.cc,
            itemValue: voucherEl.value,
            dataValue: data.clickAndCollectCost,
            title: 'Click & Collect:'
        },
        {
            item: voucherEl.delivery,
            itemValue: voucherEl.value,
            dataValue: data.deliveryCost,
            title: 'Delivery:'
        },
        {
            item: voucherEl.charity,
            itemValue: voucherEl.value,
            dataValue: data.charityPrice,
            title: 'Charity donation:'
        },
        {
            item: voucherEl.discountItem,
            itemValue: voucherEl.discountValue,
            dataValue: data.discountTotal
        },
        {
            item: voucherEl.orderTotal,
            itemValue: voucherEl.orderTotalValue,
            dataValue: data.total
        },
    ];
}

$(document).ready(function () {

    function init() {
        if (!$('.checkout-voucher').length) {
            return;
        }
        getCSRFToken();
    }

    init();
});
