﻿(function ($) {
    // This is for enabling validation on multi select and our special class to not validate
    $.validator.setDefaults({
        ignore: ".do-not-validate"
    });

    $.validator.addMethod("requireddropdownforguests", function (value, element, params) {
        var isEmptyGuest = isEmpty($(element));
        var hasValue = !this.optional(element);
        var allowNullableForBuyer = parseBool(params);
        var isBuyer = checkBuyer(element);
        
        if (hasValue) {
            return true;
        }
        else {
            if ((isEmptyGuest && !isBuyer) || (isBuyer && allowNullableForBuyer)) {
                return true;
            }
            else {
                return false;
            }
        };
    });

    $.validator.addMethod("requiredforguests", function (value, element, params) {
        var isEmptyGuest = isEmpty($(element));
        var hasValue = !this.optional(element);
        var allowNullableForBuyer = parseBool(params);
        var isBuyer = checkBuyer(element);
        
        // workaround for checkbox, where required means to be checked
        if ($(element).attr('type') == 'checkbox') {
            if ($(element).is(':checked')) {
                hasValue = true;
            }
            else {
                hasValue = false;
            }
        }
        
        if (hasValue) {
            return true;
        }
        else {
            if ((isEmptyGuest && !isBuyer) || (isBuyer && allowNullableForBuyer)) {
                return true;
            }
            else {
                return false;
            }
        };
    });

    /// A custom validation rule for requiring a property if other proptery is null. Used to validate the requirement of mobile phone or alternate phone. Can be overriden.
    /// Parameters:
    ///     - otherProperty: Other property yo check.
    ///     - overridefieldname: The override field name for overriding.
    $.validator.addMethod("requiredifnull", function (value, element, params) {
        var otherproperty = params.otherproperty;
        var overridefieldname = params.overridefieldname;

        var fieldAcceptsNullValue = $(element).closest('.card').find('.' + overridefieldname).first().val();
        var fieldAcceptsNull = parseBool(fieldAcceptsNullValue);

        if (fieldAcceptsNull)
            return true;

        if (this.optional(element)) {
            var otherProp = $('.' + otherproperty)
            return (otherProp.val() != null && otherProp.val() != '');
        }
        return true;
    });
    
    /// A custom validation rule for a property than can be overriden.
    /// Parameters:
    ///     - overridefieldname: The override field name for overriding.
    $.validator.addMethod("elprequired", function (value, element, params) {
        var overrideFieldName = params;
        var fieldAcceptsNull = false;

        if (overrideFieldName != null && overrideFieldName != '') {
            var fieldAcceptsNullValue = $(element).closest('.card').find('.' + overrideFieldName).first().val();
            var fieldAcceptsNull = parseBool(fieldAcceptsNullValue);
        }

        if (fieldAcceptsNull || (!fieldAcceptsNull && !this.optional(element))) {
            return true;
        }
        else {
            return false;
        }
    });

    /// A custom validation rule for requiring a property if other proptery has speicif value;
    /// Parameters:
    ///     - otherProperty: Other property yo check.
    ///     - otherPropertyValue: Other property value to check.
    ///     - overridefieldname: The override field name for overriding.
    $.validator.addMethod("requiredif", function (value, element, params) {
        var otherProperty = params.otherproperty;
        var otherPropertyValue = params.otherpropertyvalue;
        var overrideFieldName = params.overridefieldname;

        var fieldAcceptsNull = false;

        if (overrideFieldName != null && overrideFieldName != '') {
            var fieldAcceptsNullValue = $(element).closest('.card').find('.' + overrideFieldName).first().val();
            var fieldAcceptsNull = parseBool(fieldAcceptsNullValue);
        }

        if (fieldAcceptsNull)
            return true;

        var otherElement = $('.' + otherProperty);
        var otherElementType = otherElement.attr('type');
        var otherElementValue = '';

        if (otherElementType == 'checkbox') {
            // workaround for checkbox
            if ($(otherElement).is(':checked')) {
                otherElementValue = "true";
            }
            else {
                otherElementValue = "false";
            }
        }

        else if (otherElementType == 'radio') {
            // workaround for radios
            var otherElementValue = $('.' + otherProperty + ':checked').val().toLocaleLowerCase();
        }

        else {
            otherElementValue = $('.' + otherProperty).val().toLocaleLowerCase();
        }

        if (otherElementValue == otherPropertyValue) {
            if (this.optional(element)) {
                return false;
            }
        }

        return true;
    });

    /// A custom validation rule for a group - if one field of the group has value then all other fields must have a value 
    /// Parameters:
    ///     - group: The group name -
    $.validator.addMethod("elprequiredgroup", function (value, element, params) {
        var group = params;
        var groupIsEmpty = true;
        $("." + group).each(function (index) {
            var value = $(this).val();
            if (!valueIsEmpty(value)) {
                groupIsEmpty = false;
            }
        });

        return groupIsEmpty || !this.optional(element);
    });

    $.validator.unobtrusive.adapters.addSingleVal("requiredforguests", "allownullableforbuyer");
    $.validator.unobtrusive.adapters.addBool("requireddropdownforguests");

    /// A custom validation rule for requiring a property if other proptery is null. Used to validate the requirement of mobile phone or alternate phone. Can be overriden.
    /// Parameters:
    ///     - otherProperty: Other property yo check.
    ///     - overridefieldname: The override field name for overriding.
    $.validator.unobtrusive.adapters.add("requiredifnull", ["otherproperty", "overridefieldname"], function (options) {
        options.rules["requiredifnull"] = options.params;
        options.messages["requiredifnull"] = options.message;
    });

    /// A custom validation rule for requiring a property if other proptery has speicif value;
    /// Parameters:
    ///     - otherProperty: Other property yo check.
    ///     - otherPropertyValue: Other property value to check.
    ///     - overridefieldname: The override field name for overriding.
    $.validator.unobtrusive.adapters.add("requiredif", ["otherproperty", "otherpropertyvalue", "overridefieldname"], function (options) {
        options.rules["requiredif"] = options.params;
        options.messages["requiredif"] = options.message;
    });

    /// A custom validation rule for a group - if one field of the group has value then all other fields must have a value 
    /// Parameters:
    ///     - group: The group name
    $.validator.unobtrusive.adapters.addSingleVal("elprequiredgroup", "group");

    /// A custom validation rule for a property than can be overriden.
    /// Parameters:
    ///     - overridefieldname: The override field name for overriding.
    $.validator.unobtrusive.adapters.addSingleVal("elprequired", "overridefieldname");


}(jQuery));

// Helper

function isEmpty(current) {

    var parentCard = $(current).closest('.card.contact-dna');
    if (parentCard.length <= 0) {
        parentCard = $('.card.contact-dna');
    }

    var firstName = "";
    if ($(parentCard).find('.firstname').length !== 0) {
        firstName = $(parentCard).find('.firstname').first().val();
    }
    var lastName = "";
    if ($(parentCard).find('.lastname').length !== 0) {
        lastName = $(parentCard).find('.lastname').first().val();
    }
    var salutation = "";
    if ($(parentCard).find('.salutation').length !== 0) {
        salutation = $(parentCard).find('.salutation').first().val();
    }

    // Commented out this lines, seems to always return true
    if (Number.isNaN(firstName)) firstName = '';
    if (Number.isNaN(lastName)) lastName = '';
    if (Number.isNaN(salutation)) salutation = '';

    var fullName = salutation + firstName + lastName;
    
    return  fullName == null || fullName == '' || fullName.toUpperCase().includes('guest'.toUpperCase());
}

function valueIsEmpty(value) {
    if (value != null && value != '') return false;
    return true;
} 

function checkBuyer(element) {
    var thisIsMe = $(element).closest('.card').find('.this-is-me:checkbox').first();
   
    if ($(thisIsMe).length == 0) {
        // "This is me" check is not present, let's check hidden field
        thisIsMe = $(element).closest('.card').find('.this-is-me:hidden').first();
        if ($(thisIsMe).length > 0) {
            return parseBool($(thisIsMe).val());
        }
        else {
            return false;
        }
    }
    else {
        return $(thisIsMe).is(':checked');
    }
}