/**
 * Refreshes the nonce before submitting.
 *
 * A cached page carries a stale nonce. Rather than failing the submission and
 * losing a legally binding declaration, ask for a fresh one first.
 */
(function () {
    'use strict';

    var form = document.querySelector('.ssrc-form');

    if (!form) {
        return;
    }

    syncOrderNumber(form);
    loadLines(form);
    bindLineToggles(form);

    if (!window.ssrcForm) {
        return;
    }

    var refreshed = false;

    form.addEventListener('submit', function (event) {
        if (refreshed) {
            return;
        }

        event.preventDefault();

        var request = new XMLHttpRequest();
        request.open('POST', window.ssrcForm.ajaxUrl, true);
        request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');

        request.onloadend = function () {
            if (request.status === 200 && request.responseText) {
                var field = form.querySelector('input[name="ssrc_nonce"]');

                if (field) {
                    field.value = request.responseText.trim();
                }
            }

            refreshed = true;
            form.submit();
        };

        request.send('action=ssrc_nonce');
    });

    /**
     * Keeps the contract reference field in step with the order selector.
     *
     * Picking an order fills the number in. Picking "my order is not listed"
     * empties the field so the customer can type it themselves. The field stays
     * editable either way: the server resolves the order from the selector, so
     * the text is documentation, never the thing being trusted.
     */
    function syncOrderNumber(scope) {
        var select = scope.querySelector('#ssrc-order');
        var field = scope.querySelector('#ssrc-ref');

        if (!select || !field) {
            return;
        }

        var apply = function () {
            var option = select.options[select.selectedIndex];
            var number = option ? option.getAttribute('data-order-number') : '';

            field.value = number || '';
        };

        select.addEventListener('change', apply);

        if (select.value !== '0') {
            apply();
        }
    }

    /**
     * Fetches the product selection for the currently identified order.
     *
     * A signed in customer picks from the dropdown and the lines follow. A guest
     * types the order number and email, then asks for them explicitly - we never
     * probe on every keystroke, because each call is an order lookup.
     */
    function loadLines(scope) {
        var container = scope.querySelector('#ssrc-lines-container');

        if (!container || !window.ssrcForm) {
            return;
        }

        var select = scope.querySelector('#ssrc-order');
        var lookup = scope.querySelector('#ssrc-lookup');
        var status = scope.querySelector('#ssrc-lookup-status');
        var nonceField = scope.querySelector('input[name="ssrc_nonce"]');

        var request = function (params, onDone) {
            var xhr = new XMLHttpRequest();
            xhr.open('POST', window.ssrcForm.ajaxUrl, true);
            xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');

            xhr.onloadend = function () {
                var payload = null;

                try {
                    payload = JSON.parse(xhr.responseText);
                } catch (e) {
                    payload = null;
                }

                if (payload && payload.success && payload.data && payload.data.html) {
                    container.innerHTML = payload.data.html;
                    onDone('');
                    return;
                }

                container.innerHTML = '';
                onDone(payload && payload.data && payload.data.message ? payload.data.message : '');
            };

            xhr.send(params);
        };

        var base = function () {
            return 'action=' + encodeURIComponent(window.ssrcForm.linesAction) +
                '&nonce=' + encodeURIComponent(nonceField ? nonceField.value : '');
        };

        if (select) {
            select.addEventListener('change', function () {
                if (select.value === '0') {
                    container.innerHTML = '';
                    return;
                }

                request(base() + '&order=' + encodeURIComponent(select.value), function () {});
            });
        }

        if (lookup) {
            lookup.addEventListener('click', function () {
                var ref = scope.querySelector('#ssrc-ref');
                var email = scope.querySelector('#ssrc-email');

                if (!ref || !email || !ref.value || !email.value) {
                    if (status) {
                        status.textContent = '';
                    }
                    return;
                }

                if (status) {
                    status.textContent = '…';
                }

                request(
                    base() + '&ref=' + encodeURIComponent(ref.value) + '&email=' + encodeURIComponent(email.value),
                    function (message) {
                        if (status) {
                            status.textContent = message;
                        }
                    }
                );
            });
        }
    }

    /**
     * Unticking a product must remove it from the submission.
     *
     * The checkbox itself carries no name, so it never posts. Disabling the
     * quantity input is what actually drops the line: browsers omit disabled
     * fields from the request. Bound on the container because the lines are
     * replaced wholesale every time the order changes.
     */
    function bindLineToggles(scope) {
        var container = scope.querySelector('#ssrc-lines-container');

        if (!container) {
            return;
        }

        container.addEventListener('change', function (event) {
            var toggle = event.target;

            if (!toggle.classList || !toggle.classList.contains('ssrc-line-toggle')) {
                return;
            }

            var item = toggle.getAttribute('data-item');
            var field = container.querySelector('[name="ssrc_lines[' + item + ']"]');

            if (field) {
                field.disabled = !toggle.checked;
            }
        });
    }
}());
