'use strict';

var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var winston = require('../config/winston');
var RoleConstants = require('./roleConstants');
var PresenceSchema = require('./presence');
var TagSchema = require("../models/tag");



  var Project_userSchema = new Schema({
    id_project: {
      type: Schema.Types.ObjectId,
      ref: 'project',
      index: true
      // required: true
    },
    id_user: {      
      type: Schema.Types.ObjectId,
      ref: 'user',
      index: true
    },
    uuid_user: {
      type: String,
      index: true
      // required: true
    },
    role: {
      type: String,
      index: true
      // required: true
    },
    roleType: {
      type: Number,  //1 for agents 2 for users
      index: true
    },
    user_available: {
      type: Boolean,
      default: true, 
      index: true
      // required: true
    },
    profileStatus: {
      type: String,
    },
    presence: PresenceSchema,
    attributes: {
      type: Object,
    },
    max_assigned_chat: {
      type: Number,
    },
    number_assigned_requests: {
      type: Number,
      default:0,
      index: true
    },
    last_ip: {
        type: String,
    },
    last_login_at: {
      type: Date,
      default: new Date(),
    },
    settings: {
      type: Object,
    },
    tags: [TagSchema],
    permissions: [String],
    createdBy: {
      type: String,
      required: true
    },
    status: {
      type: String,
      enum: ['active', 'disabled'],
      default: "active",
      index: true,
      required: true
    },
    trashed: {
      type: Boolean,
      default: false,
      required: false
    }
  }, {
      timestamps: true,
      toJSON: { virtuals: true } //used to polulate messages in toJSON// https://mongoosejs.com/docs/populate.html
    }
  );

 

  //TODO COMMENT IT unused. Now events are not saved to the db
// Project_userSchema.virtual('events', {
//     ref: 'event', // The model to use
//     localField: '_id', // Find people where `localField`
//     foreignField: 'project_user', // is equal to `foreignField`
//     justOne: false,
//     // options: { getters: true }
//     options: { sort: { createdAt: -1 }, limit: 5 } // Query options, see http://bit.ly/mongoose-query-options
// });

Project_userSchema.virtual('isAuthenticated').get(function () {
  if (this.role === RoleConstants.GUEST ) {
    return false;
  }else {
    return true;
  }
});

Project_userSchema.methods.getAllPermissions = function () {
  // console.log("this", this);
  winston.debug("this.permissions", this.permissions);

  // console.log("this.rolePermissions", this.rolePermissions);
  winston.debug("this._doc.rolePermissions", this._doc.rolePermissions);

  let all = this.permissions;

  if (this._doc.rolePermissions) {
    all = [...new Set([...this.permissions, ...this._doc.rolePermissions])]; //https://medium.com/@rivoltafilippo/javascript-merge-arrays-without-duplicates-3fbd8f4881be
  }
  // const all = this.permissions.concat(this._doc.rolePermissions);
  winston.verbose("getAllPermissions all", all);

  return all;
  
}



Project_userSchema.methods.hasPermissionOrRole = function (permission, roles) {
  var all_permissions = this.getAllPermissions();
  // var all_permissions = this.getAllPermissions();
  // console.log("hasPermissionOrRole", all_permissions, permission,  this.role, roles)
  if (all_permissions && all_permissions.length>0 ) {
    if (all_permissions.includes(permission)) {
      // console.log("hasPermissionOrRole found", permission)
      return true;
    } else {
      return false;
    }
  }else {
    if (roles instanceof Array) {
      // console.log("hasPermissionOrRole roles instanceof Array");
      for (var i = 0; i < roles.length; i++) {
        if (roles[i]==this.role) {
          return true;
        }
      }
      return false;

    } else {
      // console.log("roles instanceof  ", roles instanceof );
      // console.log("this.role instanceof  ", this.role instanceof );
      
      // console.log("hasPermissionOrRole role ", this.role, roles);
      if (this.role==roles) {
        // console.log("role ok");
        return true;
      } else {
        // console.log("role ko");
        return false;
      }
    }
    
    
  }
}

Project_userSchema.methods.hasPermission = function (permission) {
  if (this.permissions && this.permissions.length>0 ) {
    if (this.permissions.includes(permission)) {
      return true;
    } else {
      return false;
    }
  }else {
    return false;
  }
}


  // var query = { id_project: req.params.projectid, id_user: req.user._id};
  // if (req.user.sub && (req.user.sub=="userexternal" || req.user.sub=="guest")) {
  //   query = { id_project: req.params.projectid, uuid_user: req.user._id};
  // }
  Project_userSchema.index({ id_project: 1, id_user: 1 }); 
  Project_userSchema.index({ id_project: 1, uuid_user: 1 }); 
  
  // Project_user.find({ id_project: projectid, role: { $in : role }
  Project_userSchema.index({ id_project: 1, role: 1 }); 
  // Project_user.find({ id_project: projectid, id_user: { $in : group[0].members}, role: { $in : [RoleConstants.OWNER, RoleConstants.ADMIN, RoleConstants.AGENT]} })
  Project_userSchema.index({ id_project: 1, id_user:1, role: 1 }); 

  // suggested by atlas
  Project_userSchema.index({ id_project: 1, role: 1, status: 1, createdAt: 1  }); 


  Project_userSchema.pre('findOneAndUpdate', async function(next) {
    // Get the update object
    const update = this.getUpdate();

    // Check if 'trashed' is being set to true
    if (update && (
        (update.trashed === true) ||
        (update.$set && update.$set.trashed === true)
      )) {
      // Set status to "disabled"
      if (!update.$set) {
        update.$set = {};
      }
      update.$set.status = "disabled";
      this.setUpdate(update);
    }
    next();
  });


  module.exports = mongoose.model('project_user', Project_userSchema);;

