/**
 * Base.Form 1.0
 *
 * Requiere
 *     Base 1.0
 */
$(function() {
    $.extend(Base, {
        Form : {

            create: function (selector, options) {

                var _i18n = {
                };

                if(options == undefined){
                    options = {}
                }

                _i18n = $.extend(true, _i18n, Base.i18n.form);

                if (options != undefined && options._i18n !== undefined && options._i18n != null) {
                    _i18n = $.extend(true, _i18n, options._i18n);
                }

                var defaultOptions = {};

                return $(selector);
            },

            _qxForm : function (form) {

                return {

                    //Example $('selector').QxForm().ver()
                    ver : function () {

                        console.log("Base.Form 1.0");
                        console.log("Requiere: Base 1.0;");
                    },

                    validate: function(options){

                        //Catch Submit Handler
                        var submitHandler = options.submitHandler;
                        delete options['submitHandler'];

                        var submitButton = options.submitButton;
                        if(null == submitButton || undefined == submitButton){
                            submitButton = $(form).find('button[actiontype="submit"]')[0];
                        }
                        delete options['submitButton'];

                        //Options
                        var _defaultOptions = {
                              setLabelErrorClass: true,
                              labelErrorClass: 'required',
                              fields: {},
                              plugins: {
                                    trigger: new FormValidation.plugins.Trigger(),
                                    bootstrap: new FormValidation.plugins.Bootstrap5({
                                        rowSelector: '.fv-row',
                                          eleInvalidClass: '',
                                          eleValidClass: ''
                                    })
                              }
                        }

                        options = $.extend(true, _defaultOptions, options);

                        //Set Required class to Fields
                        var newvaldiate = false;
                        if(options.setLabelErrorClass) {
                            $.each(options.fields, function (element, field) {

                                $.each(field.validators, function (key, value) {
                                    if (key == 'notEmpty') {

                                        $(form).find("span[for=" + element + "]").addClass(options.labelErrorClass);

                                        newvaldiate = true;
                                        return true;
                                    }

                                });
                            })
                        };

                        //Validator
                        var validator = FormValidation.formValidation(
                            form[0],
                            options
                        );
                        //Add Validator to Form
                        $(form).data("QxValidator", validator);

                        if(submitButton == undefined){
                            return validator;
                        }


                        //Default Validate-Submit Function
                        var _submitForm = function(){

                            var formValidator = $(form).QxForm().validatorInstance;
                            if (formValidator) {
                                formValidator.validate().then(function (status) {

                                    submitButton.disabled = true;

                                    if (status == 'Valid') {
                                        submitButton.setAttribute('data-kt-indicator', 'on');

                                        // Disable button to avoid multiple click
                                        submitButton.disabled = true;
                                        form.submit();
                                    } else {
                                        // Show error message.
                                        submitButton.disabled = false;
                                        submitButton.removeAttribute('data-kt-indicator');

                                        Base.Alert.custom({
                                            text: "Errores detectados al validar el formulario, por favor intente nuevamente.",
                                                icon: "error",
                                                buttonsStyling: false,
                                                confirmButtonText: "Volver al formulario!",
                                                customClass: {
                                                    confirmButton: "btn btn-primary"
                                                },
                                                callBackThen: function(result){
                                                    KTUtil.scrollTop();
                                                }
                                        });
                                    }
                                });
                            }
                        }

                        submitButton.addEventListener('click', function (e) {
                            e.preventDefault();

                            var formValidator = $(form).QxForm().validatorInstance;

                            //Custom Submit Handler
                            if(submitHandler != undefined && submitHandler != null && $.isFunction(submitHandler)) {

                               return submitHandler(form[0], formValidator, submitButton);
                            }
                            //Default Submit Handler
                            else{
                                _submitForm();
                            }
                        });

                        return $(form).QxForm().validatorInstance;
                    },

                    ajaxSubmit: function (options) {

//                        Base.Message.clear();
//
//                        var showLoading = (null != options.showLoading && options.showLoading != undefined) ? options.showLoading : true;
//                        var loadingMessage =  (null != options.loadingMessage && options.loadingMessage != undefined) ? options.loadingMessage : "Cargando...";
//
//
//                        var _defaultAjaxOptions = {
//
//                            success: function (data, textStatus, jqXHR, form) {
//
//                                if(data.type == 'Success' || data.type == 'Warning' || data.type == 'Info') {
//
//                                    if(data.message != null & data.message != "") {
//                                        Base.Message.flash(data.message, data.cssClass);
//                                    }
//
//                                    bootbox.hideAll();
//                                    Base.Loading.hide();
//
//                                    if(options.mySuccessCallBack != undefined && options.mySuccessCallBack != null && $.isFunction(options.mySuccessCallBack)) {
//
//                                        return options.mySuccessCallBack(data);
//                                    }
//
//                                    return true;
//                                }
//                                else if(data.type == 'Error' || data.type == 'Exception'){
//
//                                    Base.Message.flash(data.message, data.cssClass, options.errorContainer);
//
//                                    Base.Loading.hide();
//
//                                    return false;
//                                }
//                            }
//                        };
//
//                        var _ajaxOption = $.extend(true, _defaultAjaxOptions, options.ajaxFormOption);
//
//                        if(showLoading) {
//                            Base.Loading.show({message: loadingMessage})
//                        }
//
//                        $(form).ajaxSubmit(_ajaxOption);
                    },

                    validatorInstance: $(form).data("QxValidator"),

                    validator : {
                        callback: function(options){
                            let defaultOptions = {
                                message: "Campos con error",
                                callback: function(n){return false;}
                            }

                            options = $.extend(true, defaultOptions, options);

                            return options;
                        },
                        notEmpty: function(options){
                            let defaultOptions = {
                                message: 'Campo requerido'  //gedux.i18n.gral.messages.required
                            }

                            options = $.extend(true, defaultOptions, options);

                            return options
                        },
                        digits: function(options){
                            let defaultOptions = {
                                message: 'Por favor entre solo dígitos'  //gedux.i18n.gral.messages.digits
                            }

                            options = $.extend(true, defaultOptions, options);

                            return options
                        },
                        emailAddress: function(options){
                            let defaultOptions = {
                                message: 'Por favor entre una dirección válida'  //gedux.i18n.gral.messages.email
                            }

                            options = $.extend(true, defaultOptions, options);

                            return options
                        },
                        lessThan: function(options){
                            if(options.max === undefined || options.max === null)
                            {
                                throw new Error('El atributo max es obligatorio')
                            }

                            let defaultOptions = {
                                max: 100000000000000000000, //infinitive by default
                                message: 'Por favor entre un valor menor o igual que {0}'  //gedux.i18n.gral.messages.max
                            }

                            options = $.extend(true, defaultOptions, options);


                            if(options.max !== undefined && options.max !== null)
                            {
                                if($.isFunction(options.max))
                                {
                                    options.max = options.max()
                                }
                                options.message ='Por favor entre un valor menor o igual que '  // gedux.i18n.gral.messages.max.replace("{0}", options.max)
                            }

                            return options
                        },
                        greaterThan: function(options){
                            if(options.min === undefined || options.min === null)
                            {
                                throw new Error('El atributo min es obligatorio')
                            }
                            let defaultOptions = {
                                min: -100000000000000000000, //infinitive by default
                                message: 'Por favor entre un valor mayor o igual que {0}'  //gedux.i18n.gral.messages.min
                            }

                            options = $.extend(true, defaultOptions, options);

                            if(options.min !== undefined && options.min !== null)
                            {
                                if($.isFunction(options.min))
                                {
                                    options.min = options.min()
                                }
                                options.message = 'Por favor entre un valor mayor o igual que'  //gedux.i18n.gral.messages.min.replace("{0}", options.min)
                            }

                            return options
                        },
                        stringLength: function(options){

                            let defaultOptions = {
                                max: 250, //infinitive by default
                                min: 0,
                                message: 'Por favor entre un valor menor o igual que {0}'  //gedux.i18n.gral.messages.max + " | " + gedux.i18n.gral.messages.min
                            }

                            options = $.extend(true, defaultOptions, options);

                            let setMsgForMin = false
                            if(options != undefined && options.min !== undefined && options.min !== null)
                            {
                                if($.isFunction(options.min))
                                {
                                    options.min = options.min()
                                }
                                setMsgForMin = true
                                options.message ='Por favor entre {0} o más characters'  // gedux.i18n.gral.messages.minlength.replace("{0}", options.min)
                            }
                            if(options != undefined && options.max !== undefined && options.max !== null)
                            {
                                if($.isFunction(options.max))
                                {
                                    options.max = options.max()
                                }

                                if(!setMsgForMin){
                                    options.message ='Por favor no entre más de {0} characters'  // gedux.i18n.gral.messages.maxlength.replace("{0}", options.max)
                                }else{
                                    options.message = `Por favor, solo se admite entre ${options.min} y ${options.max} caracteres`  //gedux.i18n.gral.messages.betweenlength.replace("{0}", options.min).replace("{1}", options.max)
                                }
                            }

                            return options
                        },
                        integer: function(options){
                            let defaultOptions = {
                                message: 'Por favor entre un valor entero'  //gedux.i18n.gral.messages.integer
                            }

                            options = $.extend(true, defaultOptions, options);

                            return options
                        },
                        identical: function(options){
                            if(options.compare === undefined || options.compare === null)
                            {
                                throw new Error('El atributo compare es obligatorio')
                            }
                            let defaultOptions = {
                                message:'Las constraseñas no coinciden'  // gedux.i18n.gral.messages.equalTo
                            }

                            options = $.extend(true, defaultOptions, options);

                            return options
                        },
                        email: function(){
                            return {
                                callback: function(input){
                                    var value = $(input.element).val()

                                    return value == '' || /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/.test(value);
                                },
                                message: 'Por favor entre una dirección válida'  //gedux.i18n.gral.messages.email
                            }
                        },
                        emailWithComa: function(){
                            return {
                                callback: function(input){
                                    var value = $(input.element).val()

                                    return value == '' || /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*(,[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*)*$/.test(value);
                                },
                                message: 'Por favor entre una dirección válida'  //gedux.i18n.gral.messages.email
                            }
                        },
                        validMoney: function(){
                            return {
                                callback: function(input){
                                    var value = $(input.element).val()

                                    var exp = new RegExp("^(\\d{1,3})+(\\.\\d{2})?$","i");

                                    return exp.test(value);
                                },
                                message: 'Por favor entre un monto correcto'  //gedux.i18n.gral.messages.validMoney
                            }
                        },
                        numberwithcomma: function(){
                            return {
                                callback: function(input){
                                    var value = $(input.element).val()

                                    var exp = new RegExp("^(?:\\d+,)*\\d+$","i");

                                    return exp.test(value);
                                },
                                message: 'Por favor entre un valor numérico'  //gedux.i18n.gral.messages.number
                            }
                        },
                        strongpassword: function(){
                            return {
                                callback: function(input){
                                    var value = $(input.element).val()

                                    return (
                                        /.*([a-z]+)+.*/.test(value) &&
                                        /.*([A-Z]+)+.*/.test(value) &&
                                        /.*(\d+)+.*/.test(value) &&
                                        /.*([$@$!%*?&+_/-]+)+.*/.test(value)
                                    );
                                },
                                message: 'La contraseña debe tener al menos 8 o más caracteres con una combinación de letras, números y simbolos'
                            }
                        },
                        number: function(){
                            return {
                                callback: function(input){
                                    var value = $(input.element).val()

                                    return $.isNumeric(value)
                                },
                                message: 'Por favor entre un valor numérico'  //gedux.i18n.gral.messages.number
                            }
                        },
                        curp: function(){
                            return {
                                callback: function(input){
                                    var curp = $(input.element).val()

                                    //Validar que coincida el dígito verificador
                                    function digitoVerificador(curp17) {
                                        //Fuente https://consultas.curp.gob.mx/CurpSP/
                                        var diccionario  = "0123456789ABCDEFGHIJKLMNÑOPQRSTUVWXYZ",
                                            lngSuma      = 0.0,
                                            lngDigito    = 0.0;
                                        for(var i=0; i<17; i++)
                                            lngSuma = lngSuma + diccionario.indexOf(curp17.charAt(i)) * (18 - i);
                                        lngDigito = 10 - lngSuma % 10;
                                        if (lngDigito == 10) return 0;
                                        return lngDigito;
                                    }

                                    var re = /^([A-Z][AEIOUX][A-Z]{2}\d{2}(?:0[1-9]|1[0-2])(?:0[1-9]|[12]\d|3[01])[HM](?:AS|B[CS]|C[CLMSH]|D[FG]|G[TR]|HG|JC|M[CNS]|N[ETL]|OC|PL|Q[TR]|S[PLR]|T[CSL]|VZ|YN|ZS)[B-DF-HJ-NP-TV-Z]{3}[A-Z\d])(\d)$/,
                                        validado = curp.match(re);

                                    if (!validado)  //Coincide con el formato general?
                                        return false;


                                    if (validado[2] != digitoVerificador(validado[1]))
                                        return false;

                                    return true; //Validado
                                },
                                message: "La CURP no tiene un formato valido"
                            }
                        },
                        rfc: function(){
                            return {
                                callback: function(input){
                                    var rfc = $(input.element).val()

                                    var rfc_pattern = /^(([A-ZÑ&]{3}|[A-ZÑ&]{4})([0-9]{2})(0[13578]|1[02])((0[1-9]|[12][0-9])|3[01])([A-Z0-9]{3}))|(([A-ZÑ&]{3}|[A-ZÑ&]{4})([0-9]{2})(0[13456789]|1[012])((0[1-9]|[12][0-9])|30)([A-Z0-9]{3}))|(([A-ZÑ&]{3}|[A-ZÑ&]{4})([02468][048]|[13579][26])0229([A-Z0-9]{3}))|(([A-ZÑ&]{3}|[A-ZÑ&]{4})([0-9]{2})0229([A-Z0-9]{3}))$/i;
                                    
                                    var validado = rfc.match(rfc_pattern)
                                    if (validado == null){
                                        return false;
                                    }
                                    return true;
                                },
                                message: "La RFC no tiene un formato valido"
                            }
                        },
                        numeric: function(options){
                            let defaultOptions = {
                                message: 'Por favor entre un valor numérico'  //gedux.i18n.gral.messages.number
                            }

                            options = $.extend(true, defaultOptions, options);

                            return options
                        },
                    }
                }
            }
        }
    });

    $.fn.QxForm = function () {

        var form = this;

        return Base.Form._qxForm(form);
    }


//    $.validator.addMethod( "email", function( value, element, params ) {
//
//       return this.optional( element ) || /^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/.test( value );
//
//    }, "Please enter a valid email address.");
//
//    $.validator.addMethod("validMoney",function(value,element,param){
//
//        var exp= new RegExp("^(\\d{1,3})+(\\.\\d{2})?$","i");
//
//        return this.optional(element) || exp.test(value);
//
//    },"Por favor entre valor correcto");
//
//    $.validator.addMethod("numberwithcomma",function(value,element,param){
//
//        if(param==true){
//            var exp= new RegExp("^(?:\\d+,)*\\d+$","i");
//
//            return this.optional(element) || exp.test(value);
//        }
//
//        return this.optional(element);
//
//    },"Por favor entre solo dígitos ó dígitos separados por comas");
//
//    $.validator.addMethod("exactlydecimallength",function(value,element,param){
//
//        var exp= new RegExp("^\\d+\.\\d{"+param+"}?$","i");
//
//        return this.optional(element) || exp.test(value);
//
//    },$.validator.format("Por favor entre exactamente {0} dígitos flotantes"));
//
//    $.validator.addMethod("strongpassword", function(value, element) {
//
//        return this.optional( element )  ||  (/.*([a-z]+)+.*/.test(value) && /.*([A-Z]+)+.*/.test(value));
//
//    }, 'La contraseña debe tener al menos una Mayúscula y una Minúscula');
}); 