// Consider changing related *QuestionViewModelValidator.cs file if you change any validation rules here.

document.addEventListener('DOMContentLoaded', function () {
    let form = document.querySelector('form[id="instandaquestions"], form[action="/Public/CancelPolicy"], form[action^="/Public/DetermineClaimTypeQuestions"], form[action^="/Public/SpecificClaimTypeQuestions"]');
    if (!form) {
        return;
    }

    form.addEventListener('submit', function (e) {
        if (e.submitter?.attributes['formnovalidate']) {
            return true;
        }
        
        if (!areInstandaQuestionsValid(form)) {
            e.preventDefault();
            return false;
        }
        return true;
    });
})

function areInstandaQuestionsValid(form) {
    let inputs = form.querySelectorAll('input, select, textarea');
    inputs.forEach(input => {
        if (input.invalid) {
            removeError(input);
        }
    });
    inputs = Array.from(inputs).filter(input => (input.offsetParent !== null && !input.disabled && !input.readOnly) || input.dataset.validate);
    let invalid = false;
    for (const input of inputs) {
        runValidation(input);
        if (input.invalid) {
            invalid = true;
        }
    }
    return !invalid;
}

let runValidation = (inputEl) => {
    if (!inputEl.dataset.validationRules) {
        return;
    }

    let validationRules = JSON.parse(inputEl.dataset.validationRules);
    if (!validationRules) {
        return;
    }

    let errors = validate(inputEl, validationRules);
    if (errors.length > 0) {
        addError(inputEl, errors);
    } else {
        removeError(inputEl);
    }
};

let validate = (inputEl, validationRules) => {
    let errors = [];
    validationRules.forEach(rule => {
        switch (rule.type) {
            case 0: // minLength
                validateMinLength(inputEl.value, rule, errors);
                break;
            case 1: // maxLength
                validateMaxLength(inputEl.value, rule, errors);
                break;
            case 2: // minValue
                validateMinValue(inputEl.value, rule, errors);
                break;
            case 3: // maxValue
                validateMaxValue(inputEl.value, rule, errors);
                break;
            case 4: // required
                validateRequired(inputEl, rule, errors);
                break;
            case 5: // pattern
                validatePattern(inputEl.value, rule, errors);
                break;
            case 6: // type
                validateType(inputEl.value, rule, errors);
                break;
        }
    });
    return errors;
};

function addError(inputEl, errors) {
    inputEl.invalid = true;
    let validationDiv = findNextDiv(inputEl, 'instanda-question-validation-message')
    let span = validationDiv.querySelector('span');
    span.innerHTML = errors[0];
    span.classList.replace('field-validation-valid', 'field-validation-error');
}

function removeError(inputEl) {
    inputEl.invalid = false;
    let validationDiv = findNextDiv(inputEl, 'instanda-question-validation-message')
    let span = validationDiv.querySelector('span');
    span.innerHTML = '';
    span.classList.replace('field-validation-error', 'field-validation-valid');
}

function validateMinLength(value, rule, errors) {
    if (value !== '' && value.length < rule.value) {
        errors.push(rule.errorMessage);
    }
}

function validateMaxLength(value, rule, errors) {
    if (value !== '' && value.length > rule.value) {
        errors.push(rule.errorMessage);
    }
}

function validateMinValue(value, rule, errors) {
    if (value !== '' && value < parseFloat(rule.value)) {
        errors.push(rule.errorMessage);
    }
}

function validateMaxValue(value, rule, errors) {
    if (value !== '' && value > parseFloat(rule.value)) {
        errors.push(rule.errorMessage);
    }
}

function validateRequired(inputEl, rule, errors) {
    if (inputEl.type === 'checkbox' && !inputEl.checked) {
        errors.push(rule.errorMessage);
    } else {
        if (inputEl.value === '') {
            errors.push(rule.errorMessage);
        }
    }
}

function validatePattern(value, rule, errors) {
    if (value !== '' && !value.match(rule.value)) {
        errors.push(rule.errorMessage);
    }
}

function validateType(value, rule, errors) {
    if (value !== '' && typeof value !== rule.value) {
        errors.push(rule.errorMessage);
    }
}

function findNextDiv(input, className) {
    let container = input.parentElement;
    let element = null;
    while (element === null) {
        if (container.nextElementSibling && container.nextElementSibling.classList.contains(className)) {
            element = container.nextElementSibling;
        } else {
            container = container.parentElement;
        }
    }
    return element;
}