(function(paw, utils, Popup, Input){
    function Login2FaFormComponent($elt, popup){
        this.localization;
        this.fa2Data;
        this.settings;

        this.$elt = $elt;
        this.popup = popup;

        this.inputFields = {};
        this.dataModel = {
            phoneNumber: '',
            token: ''
        };

        this.$submit = null;
        this.$form = null;
        this.$resendToken = null;
        this.isResendLocked = true;

        this.resendPeriodLockHandler = null;
    }

    Login2FaFormComponent.prototype.markupDef = function(){
        var html = [];
        html.push('<form id="fa2-form">');
        html.push('   <div class="paw-area-v paw-nooverflow">');
        html.push('      <div class="paw-col-d paw-scrollable paw-2fa-fields">');
        html.push('         <div class="paw-area-h paw-2fa-field">');
        html.push('            <div class="paw-col-d">');
        html.push('               <div class="paw-2fa-field-label">');
        html.push('                  <label for="fa2-telephone-number">' + this.localization.phoneNumber + '</label>');
        html.push('               </div>');
        html.push('               <div class="">');
        html.push('                  <input id="fa2-telephone-number" class="form-control" type="text" disabled autocomplete="off"' + 
                                        (utils.value.isSet(this.fa2Data.phoneNumber)? ' disabled readonly' : '' ) + ' />');
        html.push('               </div>');
        html.push('            </div>');
        html.push('            <div class="paw-col paw-2fa-resend-holder">');
        html.push('               <button id="fa2-resend-token" class="btn btn-primary paw-2fa-btn" type="button">');
        html.push('                  <span>' + this.localization.sendCode + '</span>');
        html.push('               </button>');
        html.push('            </div>');
        html.push('         </div>');
        html.push('         <div class="paw-2fa-field">');
        html.push('            <div class="paw-2fa-field-label">');
        html.push('               <label for="fa2-token" class="">' + this.localization.token + '</label>');
        html.push('            </div>');
        html.push('            <div class="">');
        html.push('               <input id="fa2-token" class="form-control" type="text" autocomplete="off" />');
        html.push('            </div>');
        html.push('         </div>');
        html.push('      </div>');
        html.push('      <div class="paw-col paw-area-h paw-items-middle paw-2fa-actions">');
        html.push('         <div class="paw-col-d paw-2fa-form-error">');
        html.push('            <span></span>');
        html.push('         </div>');
        html.push('         <div class="paw-col">');
        html.push('            <button id="fa2-login" class="btn btn-primary" type="submit" disabled>');
        html.push('               <span>' + this.localization.login + '</span>');
        html.push('            </button>');
        html.push('         </div>');
        html.push('      </div>');
        html.push('   </div>');
        html.push('</form>');
        return html;
    };

    Login2FaFormComponent.prototype.init = function(){
        var self = this;
        this.$submit = $('#fa2-login');
        this.$form = $('#fa2-form');
        this.$resendToken = $('#fa2-resend-token');

        var phoneNumberSet = utils.value.isSet(this.fa2Data.phoneNumber);
        this.dataModel.phoneNumber = this.fa2Data.phoneNumber;

        this.inputFields = {
            phoneNumber: new Input(this.$elt.find('#fa2-telephone-number'), 'phoneNumber', this.dataModel),
            token: new Input(this.$elt.find('#fa2-token'), 'token', this.dataModel, undefined, function(e, val){
                self.validateRequired(val);  
                self.$elt.find('.paw-2fa-form-error > span').text("");
            })
        };

        this.$form.submit(function(e){
            self.fa2LoginFormSubmit(e);
        });

        this.$resendToken.on('click', function(){
            self.resendToken();
        });

        if(!phoneNumberSet){
            this.lockResend();
        }
    };

    Login2FaFormComponent.prototype.destroy = function(){
        this.$resendToken.off();
        if(utils.value.isSet(this.resendPeriodLockHandler)){
            clearTimeout(this.resendPeriodLockHandler);
        }
    };

    Login2FaFormComponent.prototype.resendToken = function(){
        var self = this;
        return utils.async.post(this.settings.send2FaCodeApiUrl, paw.lang.append({
            PhoneNumber: this.dataModel.phoneNumber
        }, this.settings.loginModel())).then(function(resp){
            if(!resp.Valid){
                self.$elt.find('.paw-2fa-form-error > span').text(resp.Message);
                return;
            }
            
            self.dataModel.token = '';
            self.inputFields.token.refreshValue();
            self.validateRequired(self.dataModel.token);

            self.resendPeriodLock();
        });
    };

    Login2FaFormComponent.prototype.validateRequired = function(token){
        var valid = utils.value.isSet(token) && token.length > 0;
        this.$submit.prop('disabled', !valid);
        return valid;
    };

    Login2FaFormComponent.prototype.fa2LoginFormSubmit = function(e){
        e.preventDefault();

        if(this.validateRequired(this.dataModel.token) && 
            this.validateRequired(this.dataModel.phoneNumber)){
            return this.submitToken(this.dataModel);
        }
    };

    Login2FaFormComponent.prototype.lockResend = function(){
        this.$resendToken.prop('disabled', true);
        this.isResendLocked = true;
    };
    
    Login2FaFormComponent.prototype.unlockResend = function(){
        this.$resendToken.prop('disabled', false);
        this.isResendLocked = false;
    };

    Login2FaFormComponent.prototype.resendPeriodLock = function(){
        var self = this;
        this.lockResend();
        this.resendPeriodLockHandler = setTimeout(function(){
            if(utils.value.isSet(self.dataModel.phoneNumber) && self.dataModel.phoneNumber.length > 0){
                self.unlockResend();
            }
            
            self.resendPeriodLockHandler = null;
        }, this.fa2Data.resendLockDuration * 1000);
    };

    Login2FaFormComponent.prototype.submitToken = function(data){
        var self = this;
        return utils.async.post(this.settings.submit2FaApiUrl, paw.lang.append({
            Token: data.token,
            PhoneNumber: data.phoneNumber
        }, this.settings.loginModel())).then(function(resp){
            if(!resp.Valid){
                self.settings.fa2Failed();
                self.$elt.find('.paw-2fa-form-error > span').text(resp.Message);
                return ;
            }
            self.settings.fa2Completed();
        }).catch(function(){
            self.settings.fa2Failed();
        });
    }

    paw.com.login.fa2.Login2FaFormComponent = Login2FaFormComponent;
})(paw, paw.utils, paw.com.Popup, paw.com.Input);