function isEmptyValue(val)
{
    return val === null || val === undefined || (typeof val === 'string' && !val.trim().length);
}

function validateFormData(datas, type)
{
    let hasError = false;
    /* validate required */
    datas.forEach(function(data)
    {
        const dataName  = data[0];
        const dataValue = data[1];
        const input     = $('input[name="' + dataName + '"]');

        input.parent().find('.form-tip').remove();

        const required = formConfig[type][dataName]?.required;
        var isEmpty  = isEmptyValue(dataValue);

        const name     = dists[type].form[dataName];
        let label    = $('#' + dataName + 'Label');

        if(label.length) label.remove();

        if(required && isEmpty)
        {
            hasError = true;
            label   = '<div id="' + dataName + 'Label" class="text-danger form-tip">' + validMsg.required.replace('%s', name) + '</div>';
            input.parent().append(label);
            input.addClass('has-error');
            return false;
        }
    });

    if(hasError) return false;

    /* validate number */
    datas.forEach(function(data)
    {
        const dataName  = data[0];
        const dataValue = data[1];
        let input    = $('input[name="' + dataName + '"]');

        input.parent().find('.form-tip').remove();

        const isEmpty = isEmptyValue(dataValue);
        const name    = dists[type].form[dataName];
        let label     = $('#' + dataName + 'Label');

        if(label.length) label.remove();

        const regex = /^[-+]?(\d+(\.\d*)?|\.\d+)([eE][-+]?\d+)?%?$/;
        if(formConfig[type][dataName]?.type && formConfig[type][dataName]?.type == 'number' && !isEmpty && !regex.test(dataValue))
        {
            hasError = true;
            const error = validMsg.number.replace('%s', name);
            label = '<div id="' + dataName + 'Label" class="text-danger form-tip">' + error + '</div>';
            input.parent().append(label);
            input.addClass('has-error');
            return false;
        }
    });

    if(hasError) return false;

    /* validate limit */
    datas.forEach(function(data)
    {
        const dataName  = data[0];
        const dataValue = data[1];
        const input    = $('input[name="' + dataName + '"]');

        input.parent().find('.form-tip').remove();

        const required = formConfig[type][dataName]?.required;
        const isEmpty  = isEmptyValue(dataValue);
        const name     = dists[type].form[dataName];
        let label      = $('#' + dataName + 'Label');

        if(label.length) label.remove();

        if(formConfig[type][dataName]?.type != 'number') return;

        if(!required && isEmpty) return;

        const min     = formConfig[type][dataName].min;
        const max     = formConfig[type][dataName].max;
        const noEqual = formConfig[type][dataName]?.noEqual;

        let minText = isNaN(min) ? dists[type].form[min] : min;
        let maxText = isNaN(max) ? dists[type].form[max] : max;

        let minValue = min;
        let maxValue = max;

        if(isNaN(min))
        {
            minValue = datas.find(function(x){return x[0] == min})[1];
            const minEmpty = isEmptyValue(minValue);
            minValue = minEmpty ? formConfig[type][min].min : minValue;
            minText  = minEmpty ? minValue : minText;
        }

        if(isNaN(max))
        {
            maxValue = datas.find(function(x){return x[0] == max})[1];
            const maxEmpty = isEmptyValue(maxValue);
            maxValue = maxEmpty ? formConfig[type][max].max : maxValue;
            maxText  = maxEmpty ? maxValue : maxText;
        }

        let judge = Number(dataValue) < Number(minValue) || Number(dataValue) > Number(maxValue);
        let limitError = validMsg.limit;
        if(noEqual)
        {
            judge = Number(dataValue) <= Number(minValue) || Number(dataValue) >= Number(maxValue)
            limitError = limitError.replaceAll('≤', '<');
        }
        if(judge)
        {
            hasError = true;
            const error = limitError.replace('%s', minText).replace('%s', name).replace('%s', maxText);
            label = '<div id="' + dataName + 'Label" class="text-danger form-tip">' + error + '</div>';
            input.parent().append(label);
            input.addClass('has-error');
            return false;
        }
    });

    if(hasError) return false;
}

window.submitForm = function()
{
    const url      = $('#distForm form').attr('action');
    const form     = new FormData($('#distForm form')[0]);
    const formData = Array.from(form.entries());

    form.delete('type');
    let type = '';
    $('.nav-item a').each(function()
    {
        if($(this).hasClass('active')) type = $(this).data('name');
    })
    form.append('type', type);

    if(validateFormData(formData, type) == false) return;
    $.ajaxSubmit({url, data: form});
}

$(document).on('input', '#distForm .form-control', function()
{
    $(this).removeClass('has-error');
    $(this).parent().find('.form-tip').remove();
});

window.changeNav = function(event)
{
    const activeName = $(event).find('.nav-item a:not(.active)').data('name');
    $('.desc').html(dists[activeName].describe);
}
