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

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

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

const { Reaction } = require('./reaction');
const { MyGroup } = require('./mygroup');

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

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

const tableModel = shared_consts.TABLES_ATTIVITAS;

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

const AttivitaSchema = new Schema(
  {
    ...{
      _id: {
        type: String,
        default: function () {
          return new ObjectId().toString();
        },
      },
      idapp: {
        type: String,
        required: true,
      },
      // userId: { type: Schema.Types.ObjectId, ref: 'User' },
      idSector: {
        type: Number,
      },
      idSkill: {
        type: Number,
        default: 0,
      },
      idCity: [
        {
          type: Number,
        },
      ],
      logo: {
        imagefile: {
          type: String,
        },
        alt: {
          type: String,
        },
        description: {
          type: String,
        },
      },
      photos: [
        {
          imagefile: {
            type: String,
          },
          alt: {
            type: String,
          },
          description: {
            type: String,
          },
        },
      ],
      note: {
        type: String,
        default: '',
      },
      website: {
        type: String,
      },
      date_created: {
        type: Date,
      },
      date_updated: {
        type: Date,
      },

      tipodiAttivita: {
        type: Number,
      },

      descr: {
        type: String,
      },
      note: {
        type: String,
      },

      coordinate_gps: {
        address: {
          type: String,
          default: '',
        },
        type: {
          type: String,
          enum: ['Point'], // Specifica il tipo, in questo caso solo 'Point'
          required: false,
        },
        coordinates: {
          type: [Number], // L'array dovrebbe contenere lon e lat
          required: false,
          index: '2dsphere', // Indice geospaziale  [lng, lat]
        },
      },

      email: {
        type: String,
      },
      telegram_username: {
        type: String,
      },
      cell_phone: {
        type: String,
      },
      whatsapp: {
        type: String,
      },
      createdBy: {
        // Username del creatore (proponente)
        type: String,
      },

      //**ADDFIELD_ATTIVITA
    },
    ...Reaction.getFieldsForReactions(),
    ...tools.getFieldsForAnnunci(),
  },
);

AttivitaSchema.pre('save', async function (next) {
  if (this.isNew) {
    if (!this.date_created) this.date_created = new Date();
  }

  next();
});

AttivitaSchema.statics.findAllIdApp = async function (idapp) {
  const Attivita = this;

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

  return await Attivita.aggregate(query).then((arrrec) => {
    return arrrec;
  });
};

AttivitaSchema.statics.getFieldsForSearch = function () {
  return [];
};

AttivitaSchema.statics.getFieldsLastForSearch = function () {
  return [
    { field: 'note', type: tools.FieldType.string },
    { field: 'descr', type: tools.FieldType.string },
    { field: 'recSkill.descr', type: tools.FieldType.string },
    { field: 'attivita.descr', type: tools.FieldType.string },
  ];
};

AttivitaSchema.statics.executeQueryTable = function (idapp, params, user) {
  params.fieldsearch = this.getFieldsForSearch();
  params.fieldsearch_last = this.getFieldsLastForSearch();

  const otherparams = {
    lookup1: {
      lk_tab: 'users',
      lk_LF: 'userId',
      lk_FF: '_id',
      lk_as: 'user',
      af_objId_tab: 'myId',
      lk_proj: shared_consts.getProjectForAll({}, tableModel),
    },
  };

  params = { ...params, ...otherparams };

  return tools.executeQueryTable(this, idapp, params, user);
};

AttivitaSchema.statics.getMyRecById = function (idapp, idSkill) {
  const Attivita = this;

  let query = [
    {
      $match: {
        _id: idSkill,
        idapp,
      },
    },
    {
      $sort: {
        desc: 1,
      },
    },
    {
      $addFields: {
        myId1: {
          $toObjectId: '$userId',
        },
      },
    },
    {
      $lookup: {
        from: 'users',
        localField: 'myId1',
        foreignField: '_id',
        as: 'user',
      },
    },
    {
      $replaceRoot: {
        newRoot: {
          $mergeObjects: [
            {
              $arrayElemAt: ['$user', 0],
            },
            '$$ROOT',
          ],
        },
      },
    },
    {
      $project: shared_consts.getProjectForAll({}, tableModel),
    },
    {
      $lookup: {
        from: 'skills',
        localField: 'idSkill',
        foreignField: '_id',
        as: 'recSkill',
      },
    },
    {
      $replaceRoot: {
        newRoot: {
          $mergeObjects: [
            {
              $arrayElemAt: ['$recSkill', 0],
            },
            '$$ROOT',
          ],
        },
      },
    },
    {
      $project: shared_consts.getProjectForAll({}, tableModel),
    },
    {
      $lookup: {
        from: 'sectors',
        localField: 'idSector',
        foreignField: '_id',
        as: 'sector',
      },
    },
    {
      $replaceRoot: {
        newRoot: {
          $mergeObjects: [
            {
              $arrayElemAt: ['$sector', 0],
            },
            '$$ROOT',
          ],
        },
      },
    },
    {
      $project: shared_consts.getProjectForAll({}, tableModel),
    },
    {
      $replaceRoot: {
        newRoot: {
          $mergeObjects: [
            {
              $arrayElemAt: ['$attivita', 0],
            },
            '$$ROOT',
          ],
        },
      },
    },
    {
      $project: shared_consts.getProjectForAll({}, tableModel),
    },
    {
      $lookup: {
        from: 'cities',
        localField: 'idCity',
        foreignField: '_id',
        as: 'mycities',
      },
    },
    {
      $replaceRoot: {
        newRoot: {
          $mergeObjects: [
            {
              $arrayElemAt: ['$mycities', 0],
            },
            '$$ROOT',
          ],
        },
      },
    },
  ];

  let numtab = tools.getNumTabByTable(shared_consts.TABLES_ATTIVITAS);

  const objadd = tools.addNumFavoriteAndBookmarkToQuery(idapp, numtab);
  query = [...query, ...objadd.query];

  const toadd = {
    $project: shared_consts.getProjectForAll(objadd.proj, tableModel),
  };

  query = [...query, { ...toadd }];

  return Attivita.aggregate(query).then((rec) => {
    return rec ? rec[0] : null;
  });
};

AttivitaSchema.statics.getProject = function (proj_add2) {
  let proj = {
    recSkill: 1,
    sector: 1,
    idSector: 1,
    idSkill: 1,
    idCity: 1,
    logo: 1,
    photos: 1,
    note: 1,
    descr: 1,
    website: 1,
    date_created: 1,
    date_updated: 1,
    tipodiAttivita: 1,
    coordinate_gps: 1,
    email: 1,
    telegram_username: 1,
    cell_phone: 1,
    whatsapp: 1,
    createdBy: 1,
    //**ADDFIELD_ATTIVITA
  };

  const proj_add = shared_consts.getProjectForAll(proj_add2);

  return Object.assign({}, proj, proj_add);
};

AttivitaSchema.statics.getCompleteRecord = function (idapp, id) {
  const Attivita = this;

  return Attivita.getMyRecById(idapp, id);
};

const Attivita = mongoose.model('Attivita', AttivitaSchema);

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

module.exports = { Attivita };
