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

const tools = require('../tools/general');
const { ObjectId } = require('mongodb');

const { IImg } = require('../models/myscheda');

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

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

const CatalogSchema = new Schema({
  idapp: {
    type: String,
  },
  active: {
    type: Boolean,
    default: false,
  },
  title: {
    type: String,
    index: true,
  },
  foto_collana: IImg,

  idCollane: [
    {
      type: String,
    },
  ],
  idTipoFormato: [
    {
      type: Number,
    },
  ],

  argomenti: [
    {
      type: String,
    },
  ],
  condition_andor: {
    type: Number,
    default: 0,
  },

  editore: [{ type: String }],
  editore_escludi: [{ type: String }],

  descr_introduttiva: {
    type: String,
  },
  idPageAssigned: {
    type: String,
  },
  referenti: [
    {
      type: String,
    },
  ],

  disattiva_link_immagini: Boolean,

  img_bordata: IImg,
  img_intro: IImg,
  img_bordata_stampa: IImg,
  img_intro_stampa: IImg,
  pagina_introduttiva_sfondo_nero: {
    type: Boolean,
  },
  backcolor: String,

  pdf_generato: String,
  pdf_generato_compressed: String,
  pdf_generato_size: String,
  pdf_generato_compr_size: String,
  pdf_generato_stampa: String,
  pdf_generato_stampa_compressed: String,
  pdf_generato_stampa_compr_size: String,
  pdf_generato_stampa_size: String,
  data_generato: {
    type: Date,
  },
  data_generato_stampa: {
    type: Date,
  },
  username_lista_generata: {
    type: String,
  },
  data_lista_generata: {
    type: Date,
  },
  data_lista_updated: {
    type: Date,
  },
  username_lista_updated: {
    type: String,
  },
  pdf_online: String,
  pdf_online_size: String,
  data_online: {
    type: Date,
  },
  pdf_online_stampa: String,
  pdf_online_stampa_size: String,
  data_online_stampa: {
    type: Date,
  },

  date_created: {
    type: Date,
    default: Date.now,
  },
  date_updated: {
    type: Date,
  },
  lista_prodotti: [
    {
      type: Schema.Types.ObjectId,
      ref: 'Product',
    },
  ],
  isCatalogoGenerale: Boolean,
});

/* 
TOLTO ALTRIMENTI su /settable non mi crea l'ID
CatalogSchema.pre('save', async function (next) {
  if (this.isNew) {
    this._id = new ObjectId();
  }

  next();
});
*/

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

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

/*CatalogSchema.statics.OLD_findAllIdApp = async function (idapp) {
  const Catalog = this;

  const arrrec = await Catalog.aggregate([
    // Filtra i documenti per idapp
    { $match: { idapp } },

    // Ordina i risultati per titolo
    { $sort: { title: 1 } },

    // Esegui il join con la collezione Collana
    {
      $lookup: {
        from: "collanas", // Nome della collezione Collana
        localField: "idCollane", // Campo in Catalog
        foreignField: "idCollana", // Campo in Collana
        as: "collana_info" // Nome del campo che conterrà i risultati del join
      }
    },

  ]);

  return arrrec;
};*/

CatalogSchema.statics.findAllIdApp = async function (idapp) {
  try {
    const arrrec = await this.aggregate([
      { $match: { idapp } },
      { $addFields: { num_lista_prodotti: { $size: { $ifNull: ['$lista_prodotti', []] } } } },
      { $project: { lista_prodotti: 0 } },
      { $sort: { title: 1 } },
    ]);
    return arrrec;
  } catch (err) {
    console.error('Errore:', err);
    throw err;
  }
};

CatalogSchema.statics.getCatalogById = async function (id) {
  const Catalog = this;

  try {
    let arrrec = await Catalog.find({ _id: id })
      .populate({
        path: 'lista_prodotti',
        populate: [
          {
            path: 'productInfo.idCatProds',
            model: 'CatProd',
          },
          {
            path: 'productInfo.idSubCatProds',
            model: 'SubCatProd',
          },
          {
            path: 'productInfo.idAuthors',
            model: 'Author',
          },
          {
            path: 'productInfo.idCollana',
            model: 'Collana',
          },
          {
            path: 'productInfo.idPublisher',
            model: 'Publisher',
          },
        ],
      })
      .populate({
        path: 'lista_prodotti',
        populate: {
          path: 'idProducer',
          model: 'Producer',
        },
      })
      .populate({
        path: 'lista_prodotti',
        populate: {
          path: 'idProvider',
          model: 'Provider',
        },
      })
      .populate({
        path: 'lista_prodotti',
        populate: {
          path: 'idStorehouses',
          model: 'Storehouse',
        },
      })
      .populate({
        path: 'lista_prodotti',
        populate: {
          path: 'idScontisticas',
          model: 'Scontistica',
        },
      })
      .populate({
        path: 'lista_prodotti',
        populate: {
          path: 'idGasordine',
          model: 'Gasordine',
        },
      });

    // controlla prima se nella lista ci sono dei product che non esistono piu allora li devi rimuovere !
    for (const catalog of arrrec) {
      let old_lista = [...catalog.lista_prodotti];

      let nuova_lista = [...catalog.lista_prodotti];

      const originalLength = catalog.lista_prodotti.length;
      nuova_lista = nuova_lista.filter(
        (product) =>
          product.productInfo &&
          product.productInfo.code &&
          product.productInfo.code !== '' &&
          product.productInfo.imagefile &&
          product.productInfo.imagefile !== 'noimg.jpg' &&
          !product.delete
      );

      // Se la nuova lista è diversa da quella precedente di più del 10%, allora non aggiorna, perché potrebbe esserci un problema
      let differencePercentage = (100 * Math.abs(originalLength - nuova_lista.length)) / originalLength;
      if (differencePercentage < 10) {
        // Aggiorno la lista solo se è cambiata poco
        // confronta l'array nuova_lista con l'array catalog.lista_prodotti
        let differents = tools.areDifferentProduct(catalog.lista_prodotti, nuova_lista);

        if (differents) {
          // aggiorna la lista
          catalog.lista_prodotti = nuova_lista;
          await catalog.save();
        }
      }
    }

    const transformedArrRec = arrrec.map((catalog) => ({
      ...catalog.toObject(), // Converte il documento Mongoose in un oggetto JavaScript puro
      lista_prodotti: catalog.lista_prodotti.map((product) => ({
        ...product.toObject(),
        productInfo: {
          ...product.productInfo,
          catprods: product.productInfo.idCatProds,
          subcatprods: product.productInfo.idSubCatProds,
          collana: product.productInfo.idCollana,
          authors: product.productInfo.idAuthors,
        },
        producer: product.idProducer,
        storehouse: product.idStorehouses,
        scontisticas: product.idScontisticas,
        gasordine: product.idGasordine,
      })),
    }));

    return transformedArrRec && transformedArrRec.length > 0 ? transformedArrRec[0] : null;
  } catch (err) {
    console.error('Errore: ', err);
    return null;
  }
};

CatalogSchema.statics.executeQueryPickup = async function (idapp, params) {
  const strfind = params.search;

  if (strfind === '') {
    return [];
  }

  // Cerca title
  const reg = new RegExp(strfind, 'i');
  const arrrec = await this.find({
    idapp,
    title: reg,
  })
    .sort({ title: 1 })
    .limit(10)
    .select('title _id')
    .lean();

  return arrrec;
};

const Catalog = mongoose.model('Catalog', CatalogSchema);

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

module.exports = { Catalog };
