jQuery(document).ready(function ($) {
    /* global emblueNewsletter, ajaxurl */

    var config = window.emblueNewsletter || {};

    function getAjaxUrl() {
        return config.ajaxUrl || window.ajaxurl || '/wp-admin/admin-ajax.php';
    }

    function getI18n(key) {
        return (config.i18n && config.i18n[key]) || '';
    }

    function parseAjaxResponse(raw) {
        if (raw === '-1' || raw === '0') {
            return { success: false, response: raw === '-1' ? 'invalid_nonce' : 'error' };
        }

        if (typeof raw === 'object') {
            return raw;
        }

        try {
            return JSON.parse(raw);
        } catch (error) {
            return { success: false, response: 'error' };
        }
    }

    // Subscription via form (widget or shortcode)
    var $widgetForm = $('.md__newsletter--form');

    function fetchSubscribeNonce() {
        return $.ajax({
            url: getAjaxUrl(),
            method: 'post',
            cache: false,
            data: {
                action: 'emblue_get_nonce',
                _ts: Date.now()
            },
            dataType: 'text'
        }).then(function (raw) {
            var response = parseAjaxResponse(raw);

            if (response.success && response.data && response.data.nonce) {
                return response.data.nonce;
            }

            return $.Deferred().reject('invalid_nonce');
        });
    }

    function submitSubscription(list, email, userLang, nonce) {
        return $.ajax({
            url: getAjaxUrl(),
            method: 'post',
            cache: false,
            data: {
                action: 'emblue_new',
                list: list,
                email: email,
                userLang: userLang,
                emblue_nonce: nonce,
                security: nonce,
                _ajax_nonce: nonce
            },
            dataType: 'text',
            headers: {
                'X-WP-Nonce': nonce
            }
        }).then(function (raw) {
            return parseAjaxResponse(raw);
        });
    }

    function handleSubscriptionResponse($form, response) {
        if (response.success === false || response.response === 'error' || response.response === 'invalid_nonce') {
            md_error_handling($form, response.code || 0);
            return;
        }

        md_success_handling($form, getI18n('success'));
    }

    $widgetForm.on('submit', function (e) {
        e.preventDefault();

        var $this = $(this),
            $ajaxLoader = $this.find('.md_ajax_loader'),
            email = $this.find('.md_newsletter--email_input').val(),
            userLang = $this.find('.md_newsletter--lang_input').val(),
            $privacyCheckbox = $this.find('.md_newsletter--checkbox');

        if (!$privacyCheckbox.length || $privacyCheckbox.is(':checked')) {
            if (email) {
                if (validEmail(email)) {
                    $ajaxLoader.show();
                    var list = $this.find('.md__newsletter--select').val();

                    fetchSubscribeNonce()
                        .then(function (nonce) {
                            return submitSubscription(list, email, userLang, nonce);
                        })
                        .then(function (response) {
                            handleSubscriptionResponse($this, response);
                        })
                        .fail(function () {
                            md_error_handling($this, 0, getI18n('generalError'));
                        })
                        .always(function () {
                            $ajaxLoader.hide();
                        });
                } else {
                    md_error_handling($this, 0, getI18n('emailValidation'));
                }
            } else {
                md_error_handling($this, 0, getI18n('emailText'));
            }
        } else {
            md_error_handling($this, 0, getI18n('policyValidation'));
        }
    });

    function md_success_handling($target, msg) {
        $target.next('.md_handling').remove();
        $target.after('<p class="md_handling md_success_handling">' + msg + '</p>');
    }

    function md_error_handling($target, error_code, custom_msg) {
        $target.next('.md_handling').remove();
        custom_msg || (custom_msg = getI18n('generalError'));

        var msg;

        switch (error_code) {
            case 1145:
                msg = getI18n('emailAlreadyRegistered');
                break;

            default:
                msg = custom_msg;
        }

        $target.after('<p class="md_handling md_error_handling">' + msg + '</p>');
    }

    function validEmail(email) {
        return (/(.+)@(.+){2,}\.(.+){2,}/.test(email));
    }
});
