var mongoose = require('mongoose').set('debug', false)

const _ = require('lodash');

const tools = require('../tools/general');

var server_constants = require('../tools/server_constants');

mongoose.Promise = global.Promise;
mongoose.level = "F";

const { ObjectID } = require('mongodb');

// Resolving error Unknown modifier: $pushAll
mongoose.plugin(schema => {
  schema.options.usePushEach = true
});

mongoose.set('debug', false);

var ProjectSchema = new mongoose.Schema({
  idapp: {
    type: String,
  },
  userId: {
    type: String,
  },
  pos: {
    type: Number,
  },
  descr: {
    type: String,
  },
  longdescr: {
    type: String,
  },
  typeproj: {
    type: Number,
  },
  id_main_project: mongoose.Schema.Types.ObjectId,
  id_parent: mongoose.Schema.Types.ObjectId,
  priority: {
    type: Number,
  },
  groupId: {
    type: String,
  },
  respUsername: {
    type: String,
  },
  viceRespUsername: {
    type: String,
  },
  vice2RespUsername: {
    type: String,
  },
  statusproj: {
    type: Number,
    default: 0
  },
  created_at: {
    type: Date
  },
  modify_at: {
    type: Date
  },
  completed_at: {
    type: Date
  },
  expiring_at: {
    type: Date,
  },
  enableExpiring: {
    type: Boolean,
    default: false
  },
  modified: {
    type: Boolean,
  },
  live_url: {
    type: String,
  },
  test_url: {
    type: String,
  },
  totalphases: {
    type: Number,
    default: 1
  },
  actualphase: {
    type: Number,
    default: 1
  },
  hoursplanned: {
    type: Number,
    default: 0
  },
  hoursleft: {
    type: Number,
    default: 0
  },
  hoursworked: {
    type: Number,
    default: 0
  },
  themecolor: {
    type: String,
    default: ''
  },
  themebgcolor: {
    type: String,
    default: ''
  },
  progressCalc: {
    type: Number,
    default: 0
  },
  begin_development: {
    type: Date,
  },
  begin_test: {
    type: Date,
  },
  hoursweeky_plannedtowork: {
    type: Number,
    default: 0
  },
  endwork_estimate: {
    type: Date
  },
  privacyread: {
    type: String
  },
  privacywrite: {
    type: String
  },
  tipovisu: {
    type: Number,
  },
  view: {
    type: String,
  },
  deleted: {
    type: Boolean,
    default: false,
  },

});

ProjectSchema.methods.toJSON = function () {
  var Project = this;
  var projObject = Project.toObject();

  // console.log(projObject);

  return _.pick(projObject, tools.allfieldProjectWithId());
};


ProjectSchema.statics.findByUserIdAndIdParent = function (userId, id_parent) {
  var Project = this;

  if (userId === '') {
    return Project.find({
      'id_parent': id_parent,
    });
  } else {
    return Project.find({
      'userId': userId,
      'id_parent': id_parent,
    });
  }
};

ProjectSchema.statics.findProjectByUserId = function (userId, idproj) {
  var Project = this;

  if (userId === '') {
    return Project.findOne({
      '_id': idproj,
    });
  } else {
    return Project.findOne({
      'userId': userId,
      '_id': idproj,
    });
  }
};

ProjectSchema.statics.findColorsByProject = async function (idproj) {
  const Project = this;

  let finito = false;

  let idparent = idproj;
  let colori = {};

  while (!finito) {
    let rec = await Project.findOne({ '_id': idparent });

    if (!rec)
      break;

    if (rec) {
      colori.themebgcolor = rec.themebgcolor;
      colori.themecolor = rec.themecolor
    }

    if (!rec.themebgcolor && !rec.themecolor) {
      // Cerca nel progetto ereditato
      idparent = rec.id_parent
    } else {
      break;
    }
  }

  return colori;

};


ProjectSchema.statics.findAllProjByUserId = async function (userId, idapp) {
  var Project = this;

  const query = [
    {
      $match:
        {
          $and: [
            { idapp }, {
              $or: [{ privacyread: { $ne: server_constants.Privacy.onlyme } }, { userId: userId }],
            }],
          $or: [{ deleted: { $exists: false } }, { deleted: { $exists: true, $eq: false } }],
        }
    },
    {
      $graphLookup: {
        from: "projects",
        startWith: "$id_main_project",
        connectFromField: "id_main_project",
        connectToField: "_id",
        as: "ris",
        /* restrictSearchWithMatch: {
          $or: [
            { privacyread: server_constants.Privacy.all }, { userId: userId }
          ]
        }

         */
      }
    },
    { $match: { "ris.privacyread": { $exists: true } } },

    // {
    //   $project: {
    //     "descr": 1,
    //     "typeproj": 1,
    //     "id_main_project": 1,
    //   }
    // }
  ]

  return Project.aggregate(query).then(ris1 => {

    // console.log('findAllProjByUserId', ris1);

    return ris1;
  })

  // return Project.find({
  //   $or: [
  //     { 'userId': userId },
  //     {'privacyread' : server_constants.Privacy.all}
  //     ],
  //   $or: [
  //     { 'typeproj': server_constants.TypeProj.TYPE_PROJECT },
  //     { 'typeproj': server_constants.TypeProj.TYPE_SUBDIR }
  //   ],


};

ProjectSchema.statics.getArrIdParentInTable = function (userId) {
  var Project = this;

  return Project.find(
    {
      'userId': userId,
      $or:
        [{ deleted: { $exists: false } }, { deleted: { $exists: true, $eq: false } }]
    }
  ).distinct("id_parent")

};

ProjectSchema.statics.getIdParentByIdProj = function (idProj) {
  var Project = this;

  console.log('INIT getIdParentByIdProj', idProj);

  return Project.findOne({ '_id': ObjectId(idProj) }).then(rec => {
    if (!!rec) {
      console.log('getIdParentByIdProj', rec.id_parent);
      return rec.id_parent;
    } else {
      return '';
    }
  }).catch(e => {
    return '';
  })

};

ProjectSchema.statics.creaProjMain = async function (idapp) {

  const projmain = {
    idapp,
    descr: process.env.PROJECT_DESCR_MAIN,
    longdescr: process.env.PROJECT_DESCR_MAIN,
    typeproj: 1,
    id_main_project: null,
    id_parent: null,
    privacyread: server_constants.Privacy.all
  };

  return await new Project(projmain).save()
    .then(ris => {
      console.log('ris', ris);
      if (!!ris)
        return ris._doc;
      else
        return null;
    });

};

ProjectSchema.statics.getAllProjects = async function (userId, idapp) {
  var Project = this;
  // console.log('getAllProjects');

  let obj = [];

  const projbase = await Project.findOne(
    {
      idapp,
      descr: process.env.PROJECT_DESCR_MAIN,
      $or: [{ deleted: { $exists: false } }, { deleted: { $exists: true, $eq: false } }],

    })
    .then(ris => {
      if (!!ris) {
        // console.log('ris', ris);
        if (!!ris._doc)
          return ris._doc;
        else
          return null;
      } else {
        return Project.creaProjMain(idapp);
      }
    });

  obj.arrproj = await Project.findAllProjByUserId(userId, idapp);
  obj.arrproj.push(projbase);

  //obj.arrproj = [...arrmap];

  return obj;

};

ProjectSchema.statics.enabletoModify = async function (userId, idProj) {
  var Project = this;

  let obj = [];

  return await Project.findOne({
    '_id': idProj,
    $or: [{
      privacywrite: { $ne: server_constants.Privacy.onlyme },
      userId: userId
    }]
  }).then(ris => {
    return (!!ris);
  });
};


ProjectSchema.statics.updateCalc = async function (userId, idproj, objdatacalc, recIn) {

  return new Promise((resolve, reject) => {
    if (!!recIn) {
      return resolve(recIn);
    } else {
      return resolve(Project.findProjectByUserId(userId, idproj))
    }
  }).then((myproj) => {
    if (!!myproj) {
      // console.log('objdatacalc progressCalc', objdatacalc.mydata.progressCalc);

      objdatacalc.setValuesToRecord(myproj);

      // console.log('updateCalc', myproj._id, myproj.progressCalc);

      return myproj.save()
        .then(() => {
          // console.log('salvato proj!');
          return true;
        })
        .catch(err => {
          console.log("Error updateCalc", err.message);
        });
    }
    return false;
  }).catch(e => {
    console.log('Error: ', e);
    return false;
  });

};


ProjectSchema.pre('save', function (next) {
  // console.log('Project.expiring_at', Project.expiring_at);

  next();
});


var Project = mongoose.model('Projects', ProjectSchema);

module.exports = { Project };

