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

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

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

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

const LASTVERSION = 'lastversion';

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

const VersionSchema = new Schema({
  descr: {
    type: String,
  },
  idapp: {
    type: String,
  },
  executed: {
    type: Boolean,
  },
  table: {
    type: String,
  },
  version: {
    type: Number,
  },
  date_created: {
    type: Date,
  },
});

VersionSchema.statics.isJobExecuted = async function (idapp, descr) {
  const Version = this;

  try {
    const myrec = await Version.findOne({ idapp, descr });
    return myrec.executed;
  } catch (e) {
    return false;
  }
};

VersionSchema.statics.setJobExecuted = async function (idapp, descr) {
  const Version = this;

  try {
    const myrec = await Version.findOneAndUpdate(
      { idapp, descr },
      {
        $setOnInsert: { idapp, descr },
        $set: { executed: true },
      },
      { new: true, upsert: true }
    );

    if (!myrec) {
      throw new Error(`Error setting job as executed for idapp ${idapp} and descr ${descr}`);
    }

    return myrec.executed;
  } catch (e) {
    console.error(`Error in setJobExecuted: ${e.message}`);
    return false;
  }
};

VersionSchema.statics.findAllIdApp = async function (idapp) {
  const Version = this;

  const query = [{ $sort: { descr: 1 } }];

  const res = await Version.aggregate(query).then((arrrec) => {
    return arrrec;
  });

  return res;
};

VersionSchema.statics.getLastVersionRun = async function (idapp) {
  const Version = this;

  try {
    const myrec = await Version.findOne({ idapp, table: '', descr: LASTVERSION });
    return myrec ? myrec.version : 0;
  } catch (e) {
    return 0;
  }
};

VersionSchema.statics.setLastVersionRun = async function (idapp, version) {
  const Version = this;

  try {
    const myrec = await Version.findOneAndUpdate(
      { idapp, table: '', descr: LASTVERSION },
      {
        $setOnInsert: { idapp, table: '', descr: LASTVERSION },
        $set: { version },
      },
      { new: true, upsert: true }
    );

    return !!myrec;
  } catch (e) {
    console.error(`Error in setLastVersionTable: ${e.message}`);
    return false;
  }
};




VersionSchema.statics.isTableVersionUpdated = async function (idapp, table) {
  const Version = this;

  const lastversion = await Version.getLastVersionRun(idapp);

  try {
    const myrec = await Version.findOne({ idapp, table });
    return myrec.version === lastversion;
  } catch (e) {
    return false;
  }
};

VersionSchema.statics.updateTableVersion = async function (idapp, table, version) {
  const Version = this;

  try {
    const myrec = await Version.findOneAndUpdate(
      { idapp, table },
      {
        $setOnInsert: { idapp, table },
        $set: { version },
      },
      { new: true, upsert: true }
    );

    return !!myrec;
  } catch (e) {
    console.error(`Error in updateTableVersion: ${e.message}`);
    return false;
  }
};



const Version = mongoose.model('Version', VersionSchema);

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

module.exports = { Version };
