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

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

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

const shared_consts = require('../tools/shared_nodejs');

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


const JobsInProgressSchema = new Schema({
  idapp: {
    type: String,
  },
  descr: {
    type: String,
  },
  nomeFunzioneDbOp: {
    type: String,
  },
  status: {
    type: Number,
  },
  terminatedWhy: {
    type: Number,
  },
  comment: {
    type: String,
  },
  date_created: {
    type: Date,
    default: Date.now
  },
});

JobsInProgressSchema.statics.chechifExistJobWorking = async function (jobData, terminateiftoolong) {

    // controlla se esiste un altro job, non ancora terminato !STATUS_JOB.FINISH
  // se esiste già allora ritorna false
  const existingJob = await this.findOne({ idapp: jobData.idapp, nomeFunzioneDbOp: jobData.nomeFunzioneDbOp, status: { $ne: shared_consts.STATUS_JOB.FINISH } });
  if (existingJob) {
    // se il Job trovato è passato troppo tempo (oltre 3 ore date_created), allora fai finta che abbia già terminato 
    // (in questo caso, non ritorna false, ma ritorna il job trovato, per permettere di gestire il caso in cui si vuole forzare il job a terminare)
    if (Math.abs(Date.now() - existingJob.date_created.getTime()) > 180 * 60 * 1000) {
      if (terminateiftoolong) {
        existingJob.status = shared_consts.STATUS_JOB.FINISH;
        existingJob.terminatedWhy = shared_consts.TERMINATED_WHY.TOOLONGTIME;
        await existingJob.save();
        return false;
      }
    } else {
      return true; // E' in FUNZIONE il JOB
    }
  }

  return false;
};

JobsInProgressSchema.statics.addNewJob = async function (jobData) {
  if (!jobData || typeof jobData !== 'object') {
    console.error('ERRORE: ❌ jobData deve essere un oggetto valido');
  }

  const esistegia = await this.chechifExistJobWorking(jobData, true);

  if (esistegia) {
    return null;
  }

  try {
    const newJob = await this.create(jobData);
    return newJob;
  } catch (err) {
    console.error('Errore nell\'aggiungere un nuovo record: ', err);
    throw err;
  }
};

JobsInProgressSchema.methods.terminateJob = async function (witherror) {
  try {
    
    this.status = shared_consts.STATUS_JOB.FINISH;
    this.terminatedWhy = witherror ? shared_consts.TERMINATED_WHY.END_WITHERROR : shared_consts.TERMINATED_WHY.END_NORMALLY;
    await this.save();
    return true;
  } catch (err) {
    console.error('Errore durante la terminazione del job: ', err);
    return false;
  }
};


JobsInProgressSchema.statics.getFieldsForSearch = function () {
  return [{ field: 'descr', type: tools.FieldType.string }]
};

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

JobsInProgressSchema.statics.findAllIdApp = async function (idapp) {
  const JobsInProgress = this;

  try {
    return await JobsInProgress.find({ idapp }).then((arrrec) => {
      return arrrec;
    });

  } catch (err) {
    console.error('Errore: ', err);
  }
};

const JobsInProgress = mongoose.model('JobsInProgress', JobsInProgressSchema);

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


module.exports = { JobsInProgress };
