const mongoose = require('mongoose').set('debug', false)
const Schema = mongoose.Schema;

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

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

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


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

const SettingsSchema = new Schema({
  idapp: {
    type: String,
  },
  key: {
    type: String,
  },
  type: {
    type: Number,
  },
  value_str: {
    type: String,
  },
  value_date: {
    type: Date,
  },
  value_num: {
    type: Number,
  },
  value_bool: {
    type: Boolean,
  },
  serv: {
    type: Boolean,
    default: false
  },
  crypted: {
    type: Boolean,
    default: false
  }
});

SettingsSchema.statics.getFieldsForSearch = function () {
  return [{ field: 'key', type: tools.FieldType.string },
  { field: 'value_str', type: tools.FieldType.string }, { field: 'value_num', type: tools.FieldType.number }]
};

SettingsSchema.statics.executeQueryTable = function (idapp, params) {
  params.fieldsearch = this.getFieldsForSearch();
  return tools.executeQueryTable(this, idapp, params);
};

SettingsSchema.statics.getValDbSettings = function (idapp, key, def) {
  return Settings.findOne({ idapp, key })
    .then((myrec) => {
      // console.log('getValDbSettings', myrec, 'idapp', idapp);
      if (!!myrec) {
        if (myrec.type === tools.FieldType.date)
          return myrec.value_date;
        else if ((myrec.type === tools.FieldType.number) || (myrec.type === tools.FieldType.hours))
          return myrec.value_num;
        else if (myrec.type === tools.FieldType.boolean)
          return myrec.value_bool;
        else if (myrec.type === tools.FieldType.crypted)
          return tools.decryptdata(myrec.value_str);
        else
          return myrec.value_str;
      } else {
        return def
      }

    }).catch((err) => {
      console.error('getValDbSettings', err);
      return def;
    });

};

SettingsSchema.statics.DuplicateAllRecords = async function (idapporig, idappdest) {

  return await tools.DuplicateAllRecords(this, idapporig, idappdest);

};

SettingsSchema.statics.findAllIdApp = async function (idapp, serv, crypted = false) {
  const Settings = this;

  try {
    let myfind = '';
    if (serv) {
      myfind = { idapp, serv };
    } else
      myfind = { idapp };

    // myfind = {...myfind, $or: [{ crypted: { $exists: false } }, { crypted: { $exists: true, $eq: crypted } }]};

    const arrorig = await Settings.find(myfind).lean();

    let myarr = []

    if (!crypted) {
      for (let rec of arrorig) {
        if (rec.crypted) {
          rec.value_str = ''
        }
        myarr.push({ ...rec });
      }
    } else {
      myarr = [...arrorig];
    }

    return myarr;
  } catch (e) {
    console.error('Settings: findAllIdApp', e);
    return null;
  }

};

SettingsSchema.statics.setKeyNum = async function (idapp, key, value) {
  const Settings = this;

  let myrec = await Settings.findOne({ idapp, key });
  if (!myrec) {
    myrec = new Settings({ key });
    myrec._id = new ObjectId();
    myrec.idapp = idapp;
    myrec.type = tools.FieldType.number;
    myrec.value_num = value;

    return await myrec.save();
  } else {
    myrec = await Settings.findOneAndUpdate({ idapp, key },
      { $set: { value_num: value } },
      { new: false });
  }

  return myrec

};

SettingsSchema.statics.setBool = async function (idapp, key, valbool) {
  const Settings = this;

  let myrec = await Settings.findOne({ idapp, key });
  if (!myrec) {
    myrec = new Settings({ key });
    myrec._id = new ObjectId();
    myrec.idapp = idapp;
    myrec.type = tools.FieldType.boolean;
    myrec.value_bool = valbool;

    return await myrec.save();
  } else {
    myrec = await Settings.findOneAndUpdate({ idapp, key }, { $set: { value_bool: valbool } }, { new: false });
  }

  return myrec

};


SettingsSchema.statics.getKeyNum = async function (idapp, key, mydefault) {
  const Settings = this;

  const ret = await Settings.findOne({ idapp, key });
  if (!!ret) {
    return ret.value_num;
  } else {
    return mydefault;
  }

};

const Settings = mongoose.model('Settings', SettingsSchema);

Settings.createIndexes()
  .then(() => { })
  .catch((err) => { throw err; });


module.exports = { Settings };
