const ONLINE = {};
const COOKIE = '__user';
const TOKEN = '__token';
const SECRET = 'js.latoT';
const EXPIRE = '3 days';
const EXPIREONLINE = '5 minutes';
const dbaseA=CONFIG("dbaseA");
const conURLA=CONFIG("conURLA");

//7 days
AUTH(async function($) {
    //console.log("ONLINE1");
    //console.log($.ua);
    var cookie = $.cookie(COOKIE);
    if (!cookie || cookie.length < 20){
        $.invalid();
        return;
    }
    // Decrypt the cookie value
    cookie = F.decrypt(cookie, SECRET);
    if (!cookie){
        $.invalid();
        return;
    }
    $.roles(cookie.role);
    
    var session = ONLINE[cookie._id];
    //console.log("ONLINE2");
    //console.log(ONLINE);

    if (session) {
      // User is online, so we increase his expiration of session
        session.ticks = F.datetime.getTime();
        $.success(session);
        //console.log("ONLINE3");
        //console.log(ONLINE);
        return;
    }
    //console.log("ONLINE333333333");
    //console.log(ONLINE);
    // userId=cookie._id*1;
    // var nosql = NOSQL('users');
    var on=await nosFIND(cookie);
    //console.log(on);
    if(on){
      $.success(cookie);
      ONLINE[cookie._id] = cookie;
      return;
    }else{
      $.invalid();
      return;
    }
    // nosql.one().where('id', userId).callback(function(err, user) {
    //       // Check whether the user exists in DB
    //     if (err || !user) {
    //         // If not, then remove the cookie
    //         $.cookie(COOKIE, '', '-1 day');
    //         $.invalid();
    //         return ;
    //     } 
    //     user.ticks = F.datetime.getTime();
    //     console.log("user auth");
    //     console.log(user);
    //       // Create a session
    //     ONLINE[user._id] = user;
    //     console.log("ONLINE4");
    //     console.log(ONLINE);
     
    //       // Authorize the user
    //     $.success(user);
    //       return;
    //   });

 });
  // A simple service cleaner for expired sessions
  F.on('service', function(counter) {
      if (counter % 5 !== 0)
          return;
      var countonline = Object.keys(ONLINE);
       var ticks = F.datetime.getTime();
       //console.log(ticks);
       //console.log(ONLINE);
      // for (var i = 0; i < countonline; i++) {
      //   //console.log(ONLINE['7']);
      //   console.log(ONLINE['7']);
      //   if (ONLINE[i].ticks < ticks)
      //         delete ONLINE[i];
      // }
      for (x in ONLINE) 
         if (ONLINE[x].ticks < ticks)
               delete ONLINE[x];

      if (counter % 20 === 0)
        nosDEL(ticks);
  });
  // A simple method for creating an token cookie
  F.pagetoken =async function(controller) {
    // user.ip = controller.ip;
    //controller.header('X-Protection', '1; mode=block');
    controller.cookie(COOKIE2, "X-Protection", '7 days');
    return F;
  };

  F.smslogin =async function(controller,dbaseA,phone,project) {
    controller.repository.user={};
    controller.repository.login={status:false,sms:""};
    const mongo=MODULE('https_modules/HmongoDB');
    const s=await  mongo.connfull(conURLA);
        console.log("--------------s.status--------------"); 
      console.log(s.status);
   if(s.status==200){
      var user=await mongo.join2merge(s.data,dbaseA,"user","_id","user-info","_id",{username:phone},project);
        console.log("--------------user--------------"); 
      console.log(user);
      if(user.status==500){
           controller.repository.login.sms=500;
      }else if(user.status==200){
          if(user.data[0].active){
              controller.repository.login.status=true;
          }else{
              controller.repository.login.sms=105;
          }
      }else{
         user["data"]=[];
         var d={"username":""+phone,"role":"customer","password":"","active":true};
        var res=await mongo.insertONE(s.data,dbaseA,"user",d);
//  console.log("---------------/////---------------");
// console.log("---------------/////---------------");
// console.log(res);
// console.log(res.data.insertedId);

// console.log("---------------\\\\---------------");
// console.log("---------------\\\\\---------------");
           controller.repository.login.sms=201;
          controller.repository.login["id"]=res.data.insertedId;
          d={"_id":res.data.insertedId,"phone":[{"k":"تلفن همراه","v":""+phone}]};
         res=await mongo.insertONE(s.data,dbaseA,"user-info",d);
         user.data[0]={"_id":res.data.insertedId,"role":"customer","name":"","fam":"","active":true};
            controller.repository.login.status=true;
      }
      
    
      
      if(controller.repository.login.status){
        //F.datetime.add('-' + EXPIREONLINE);
// console.log("---------------worod---------------");
        var d=new Date(F.datetime.add(EXPIRE));
        user.data[0].ticks = d.getTime();
        user.data[0].ua=controller.ua;
        controller.repository.user=user.data[0];
        // Create a session
        var k=await nosINS(user.data[0]);
// console.log("---------------k---------------");
// console.log(k);

        if(k){
          // Create a online session
          ONLINE[user.data[0]._id] = user.data[0];
          d=new Date(F.datetime.add(EXPIREONLINE));
          ONLINE[user.data[0]._id].ticks = d.getTime();
          controller.cookie(COOKIE, F.encrypt(user.data[0], SECRET), EXPIRE);
                // We can add another security elements e.g.: User-Agent, IP address, etc.
          //      // user.ip = controller.ip;
            //controller.header('X-Protection', '1; mode=block');

        }
//  console.log("---------------khoroj---------------");
     }
    }else{
          controller.repository.login.sms=501;
    }
      mongo.disconn(s.data);
    
      return F;
  };




  F.userlogin =async function(controller,dbaseA,user,pass,project) {
    controller.repository.user={};
    controller.repository.login={status:false,sms:0};
    // console.log(controller.ua);
    // console.log(controller.ip);
    // console.log(controller.mobile);
    // console.log(controller.robot);
  //  console.log(controller.req.headers);
    const v=MODULE('https_modules/Hvalidation');
    if(v.FISphone(user) && v.ISstring(pass,6)){
        const x=MODULE('https_modules/HmongoDB');
        const s=await x.connfull(conURLA);
        // console.log(s);
        // console.log(user);
        // console.log(pass);
        if(s.status==200){
          var user=await x.join2merge(s.data,dbaseA,"user","_id","user-info","_id",{username:user,password:pass},project);
        //  console.log(user);
          if(user.status==200 && user.data.length==1){
            //F.datetime.add('-' + EXPIREONLINE);
            // console.log("1111111111111111111");
            var d=new Date(F.datetime.add(EXPIRE));
            user.data[0].ticks = d.getTime();
            user.data[0].ua=controller.ua;
            controller.repository.user=user.data[0];
            // Create a session
            var k=await nosINS(user.data[0]);
            if(k){
              // Create a online session
              ONLINE[user.data[0]._id] = user.data[0];
              d=new Date(F.datetime.add(EXPIREONLINE));
              ONLINE[user.data[0]._id].ticks = d.getTime();
              controller.cookie(COOKIE, F.encrypt(user.data[0], SECRET), EXPIRE);
                    // We can add another security elements e.g.: User-Agent, IP address, etc.
              //      // user.ip = controller.ip;
                //controller.header('X-Protection', '1; mode=block');
              controller.repository.login.status=true;
            }
          }else{
              controller.repository.login.sms=499;
          }
          x.disconn(s.data);
        }else{
              controller.repository.login.sms=501;
        }
    }else{
        controller.repository.login.sms=406;
    }

    
    
    
    
      return F;
  };
  F.userloginATregister =async function(controller,dbaseA,user_instance) {
    controller.repository.user={};
    controller.repository.login=false;
        var user=user_instance;
        var d=new Date(F.datetime.add(EXPIRE));
        user.ticks = d.getTime();
        user.ua=controller.ua;
        controller.repository.user=user;
        // Create a session
        var k=await nosINS(user);
        if(k){
          // Create a online session
          ONLINE[user._id] = user;
          d=new Date(F.datetime.add(EXPIREONLINE));
          ONLINE[user._id].ticks = d.getTime();
          controller.cookie(COOKIE, F.encrypt(user, SECRET), EXPIRE);
                // We can add another security elements e.g.: User-Agent, IP address, etc.
          //      // user.ip = controller.ip;
            //controller.header('X-Protection', '1; mode=block');
          controller.repository.login=true;

       }
      return F;
  }; 
  
  // The method removes auth cookie
  F.userlogoff = function(controller) {
      // console.log("---------------logoff---------------");

      controller.cookie(COOKIE, '', '-1 day');
      var cookie = F.decrypt(cookie, SECRET);

      nosDELcut(cookie)
      return F;
  };

  nosFIND=async function(user){
    var nosql = NOSQL('sessions');
    return await new  Promise(async(resolve, reject) => {
      try{
        nosql.find().where('ticks', '=', user.ticks).where('id', '=', user._id).where('role', '=', user.role).where('ua', '=', user.ua).callback(function(err, response) {
          if(err)
            resolve(false);
          resolve(true);
        });
      }catch(err){
          output.status=500;
          output.data=err;
          resolve(output);

      }
    });
  }
  nosINS=async function(user){
    var nosql = NOSQL('sessions');
    return await new  Promise(async(resolve, reject) => {
      try{
        nosql.insert({id:user._id,role:user.role,ticks:user.ticks,ua:user.ua}).callback(function(err, response) {
          if(err)
            resolve(false)
          resolve(true);
        });
      }catch(err){
          // output.status=500;
          // output.data=err;
          resolve(false);

      }
    });
  }
  nosDEL=async function(time){
    var nosql = NOSQL('sessions');
    return await new  Promise(async(resolve, reject) => {
      try{
        nosql.remove().where('ticks', '<', time).callback(function(err, response) {
          resolve(true);
        });
      }catch(err){
          // output.status=500;
          // output.data=err;
          resolve(false);

      }
    });
  }
  nosDELcut=async function(user){
    var nosql = NOSQL('sessions');
    return await new  Promise(async(resolve, reject) => {
      try{
        nosql.remove().where('ticks', '=', user.ticks).where('id', '=', user._id).where('role', '=', user.role).callback(function(err, response) {
          resolve(true);
        });
      }catch(err){
          // output.status=500;
          // output.data=err;
          resolve(false);

      }
    });
  }

  

  
  