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

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

const Order = require('../models/order');
var { User } = require('../models/user');

const Storehouse = require('../models/storehouse');
const Provider = require('../models/provider');
const Gasordine = require('../models/gasordine');
const Product = require('../models/product');

const { Circuit } = require('../models/circuit');

const CartClass = require('../modules/Cart')
const Cart = require('../models/cart');

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


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

const OrdersCartSchema = new Schema({
  idapp: {
    type: String
  },
  numorder: { type: Number },
  numord_pers: { type: Number },
  userId: { type: Schema.Types.ObjectId, ref: 'User' },
  totalQty: { type: Number, default: 0 },
  totalQtyPreordered: { type: Number, default: 0 },
  totalPrice: { type: Number, default: 0 },
  totalPriceCalc: { type: Number, default: 0 },
  totalPriceIntero: { type: Number, default: 0 },
  department: {
    type: String, ref: 'Department'
  },
  items: [
    {
      order:
        { type: Schema.Types.ObjectId, ref: 'Order' }
    }
  ],
  status: {
    type: Number,
    Default: 0,
  },
  confermato: {  // e quindi è stato tolto dal magazzino (aggiornando il campo stockBloccatiQty)
    type: Boolean,
    default: false,
  },
  date_confermato: {
    type: Date
  },
  pagato: {
    type: Boolean,
    default: false,
  },
  date_pagato: {
    type: Date
  },
  spedito: {
    type: Boolean,
    default: false,
  },
  date_spedito: {
    type: Date
  },
  consegnato: { // e quindi è stato tolto dal magazzino (aggiornando il campo stockQty e stockBloccatiQty)
    type: Boolean,
    default: false,
  },
  date_consegnato: {
    type: Date
  },
  preparato: {
    type: Boolean,
    default: false,
  },
  date_preparato: {
    type: Date
  },
  ricevuto: {
    type: Boolean,
    default: false,
  },
  date_ricevuto: {
    type: Date
  },
  note: {
    type: String
  },
  codice_sconto: {
    type: String
  },
  descr_sconto: {
    type: String
  },
  note_per_gestore: {
    type: String
  },
  note_ordine_gas: {
    type: String
  },
  note_per_admin: {
    type: String
  },
  modify_at: {
    type: Date
  },
  created_at: {
    type: Date
  },
  deleted: {
    type: Boolean,
    default: false,
  },
});

var OrdersCart = module.exports = mongoose.model('OrdersCart', OrdersCartSchema);

function fixupdated(myrec) {
  return myrec;
  /*if (myrec) {
    if (myrec.totalPriceCalc === undefined) {
      myrec.totalPriceCalc = myrec.totalPrice;
    }
  }
  return myrec;*/
}

module.exports.findAllIdApp = async function (idapp, userId) {
  const myfind = { idapp, userId, deleted: false };

  return await await OrdersCart.find(myfind);
};

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

module.exports.getFieldsForSearch = function () {
  return [{ field: 'note', type: tools.FieldType.string }]
};


module.exports.getLastNumOrder = async function (idapp) {
  let query = { idapp, deleted: false }
  let numorder = 100;
  let numorderrec = await OrdersCart.find(query).sort({ numorder: -1 }).limit(1);

  if (numorderrec && numorderrec.length > 0)
    numorder = numorderrec[0].numorder;
  else
    numorder = 100;

  return numorder;

};

module.exports.getLastNumOrdPers = async function (uid, idapp) {
  let query = { userId: uid, idapp, deleted: false }
  let numorder = 1;
  let numorderrec = await OrdersCart.find(query).sort({ numord_pers: -1 }).limit(1);

  if (numorderrec && numorderrec.length > 0)
    numorder = numorderrec[0].numord_pers;
  else
    numorder = 0;

  return numorder;

};

module.exports.getStatusCartByUserId = async function (uid, idapp, numorder) {
  let query = { userId: uid, idapp, status: { $gte: shared_consts.OrderStatus.CHECKOUT_SENT } }
  let myorderscart = null;
  if (numorder > 0) {
    query = { userId: uid, idapp, numorder, status: { $gte: shared_consts.OrderStatus.CHECKOUT_SENT } }
  }

  myorderscart = await OrdersCart.findOne(query);

  if (!!myorderscart)
    return myorderscart.status;
  else
    return shared_consts.OrderStatus.NONE

}

module.exports.getRecCartByUserId = async function (uid, idapp, numorder) {
  let query = { userId: uid, idapp, status: { $lt: shared_consts.OrderStatus.CHECKOUT_SENT } }
  let myorderscart = null;
  if (numorder > 0) {
    query = { userId: uid, idapp, numorder, status: { $lt: shared_consts.OrderStatus.CHECKOUT_SENT } }
  }

  myorderscart = await OrdersCart.findOne(query).lean();

  return myorderscart
}

module.exports.getOrdersCartById = async function (id) {

  let query = { _id: new mongoose.Types.ObjectId(id) };

  const arrris = await OrdersCart.getOrdersCartByQuery(query);
  let myrec = arrris && arrris.length > 0 ? arrris[0] : null;
  myrec = fixupdated(myrec);
  return myrec;

}


module.exports.getOrdersCartByQuery = async function (query) {
  try {

    let myorderscart = await OrdersCart.find(query)
      .populate('items.order')
      .populate({
        path: 'items.order',
        populate: {
          path: 'idProduct',
          model: 'Product',
        }
      })
      .populate({
        path: 'items.order',
        populate: {
          path: 'idProducer',
          model: 'Producer'
        }
      })
      .populate({
        path: 'items.order',
        populate: {
          path: 'idProvider',
          model: 'Provider'
        }
      })
      .populate({
        path: 'items.order',
        populate: {
          path: 'idGasordine',
          model: 'Gasordine'
        }
      })
      .populate({
        path: 'items.order',
        populate: {
          path: 'idStorehouse',
          model: 'Storehouse'
        }
      })
      .populate({
        path: 'items.order',
        populate: {
          path: 'idScontisticas',
          model: 'Scontistica'
        }
      })
      .populate({
        path: 'userId',
        model: 'User',
        select: '_id name surname username profile email lang'
      })
      .lean();

    myorderscart = myorderscart.map(order => {
      order.user = order.userId;
      order.userId = order.user._id;
      order.items = order.items.map(item => {
        if (item.order) {
          try {
            item.order.product = { ...item.order.idProduct };
            item.order.idProduct = item.order.product ? item.order.product._id : '';
            item.order.producer = item.order.idProducer;
            item.order.idProducer = item.order.producer ? item.order.producer._id : '';
            item.order.storehouse = item.order.idStorehouse;
            item.order.idStorehouse = item.order.storehouse ? item.order.storehouse._id : '';
            item.order.provider = item.order.idProvider;
            item.order.idProvider = item.order.provider ? item.order.provider._id : '';
            item.order.gasordine = item.order.idGasordine;
            item.order.idGasordine = item.order.gasordine ? item.order.gasordine._id : '';
            item.order.scontisticas = item.order.scontisticas;
            item.order.idScontisticas = item.order.idScontisticas ? item.order.idScontisticas._id : '';
          } catch (e) {
            console.error('Err: ', e);
          }
        }
        return item;
      });
      return order;
    });

    myorderscart = fixupdated(myorderscart);

    /*
    let myquery = [
      { $match: query }, // Match documents based on your query
      {
        $unwind: "$items"
      },
      {
        $lookup: {
          from: "orders", // Assuming the referenced collection is named "orders"
          localField: "items.order",
          foreignField: "_id",
          as: "items.order"
        }
      },
      {
        $unwind: {
          path: "$items.order",
          preserveNullAndEmptyArrays: true // Preserve items with no matching orders
        }
      },
      {
        $lookup: {
          from: "products",
          localField: "items.order.idProduct",
          foreignField: "_id",
          as: "items.order.product"
        }
      },
      {
        $unwind: {
          path: "$items.order.product",
          preserveNullAndEmptyArrays: true // Preserve items with no matching orders
        }
      },
      // Populate 'items.order.idProduct.idProductInfo' with 'ProductInfo'
      {
        $lookup: {
          from: "productinfos",
          localField: "items.order.product.idProductInfo",
          foreignField: "_id",
          as: "items.order.product.productInfo"
        }
      },
      { $unwind: "$items.order.product.productInfo" }, // Deconstruct the array

      // Populate 'items.order.idProducer' with 'Producer'
      {
        $lookup: {
          from: "producers",
          localField: "items.order.product.IdProducer",
          foreignField: "_id",
          as: "items.order.producer"
        }
      },
      {
        $unwind: {
          path: "$items.order.producer",
          preserveNullAndEmptyArrays: true // Preserve items with no matching orders
        }
      },

      // Populate 'items.order.idProvider' with 'Provider'
      {
        $lookup: {
          from: "providers",
          localField: "items.order.idProvider",
          foreignField: "_id",
          as: "items.order.provider"
        }
      },
      {
        $unwind: {
          path: "$items.order.provider",
          preserveNullAndEmptyArrays: true // Preserve items with no matching orders
        }
      },

      // Populate 'items.order.idGasordine' with 'Gasordine'
      {
        $lookup: {
          from: "gasordines",
          localField: "items.order.idGasordine",
          foreignField: "_id",
          as: "items.order.gasordine"
        }
      },
      {
        $unwind: {
          path: "$items.order.gasordine",
          preserveNullAndEmptyArrays: true // Preserve items with no matching orders
        }
      },

      // Populate 'items.order.idStorehouse' with 'Storehouse'
      {
        $lookup: {
          from: "storehouses",
          localField: "items.order.idStorehouse",
          foreignField: "_id",
          as: "items.order.storehouse"
        }
      },
      {
        $unwind: {
          path: "$items.order.storehouse",
          preserveNullAndEmptyArrays: true // Preserve items with no matching orders
        }
      },

      // Populate 'items.order.idScontisticas' with 'Scontistica'
      {
        $lookup: {
          from: "scontisticas",
          localField: "items.order.product.idScontisticas",
          foreignField: "_id",
          as: "items.order.scontisticas"
        }
      },
      {
        $unwind: {
          path: "$items.order.scontisticas",
          preserveNullAndEmptyArrays: true // Preserve items with no matching orders
        }
      },

      // Populate 'userId' with 'User'
      {
        $lookup: {
          from: "users",
          localField: "userId",
          foreignField: "_id",
          as: "user"
        }
      },

      {
        $unwind: {
          path: "$user",
          preserveNullAndEmptyArrays: true // Preserve items with no matching orders
        }
      },
      {
        $group: {
          _id: "$_id",
        }
      },
      {
        $project: {
          _id: 1,
          'user.name': 1,
          'user.surname': 1,
          'user.username': 1,
          'user.profile': 1,
          'user.email': 1,
          'user.lang': 1,
          'totalQty': 1,
          'totalQtyPreordered': 1,
          'totalPrice': 1,
          "totalPriceCalc": 1,
          "confermato": 1,
          "pagato": 1,
          "spedito": 1,
          "consegnato": 1,
          "preparato": 1,
          "ricevuto": 1,
          "deleted": 1,
          "idapp": 1,
          "items": 1,
          "userId": 1,
          "status": 1,
          "note": 1,
          "numorder": 1,
          "numord_pers": 1,
          "created_at": 1,
          "modify_at": 1,
        }
      }
    ];

    // Project to select specific fields from 'User'
    /*{
      $project: {
        "_id": 1,
        "name": "$userId.name",
        "surname": "$userId.surname",
        "username": "$userId.username",
        "profile": "$userId.profile",
        "email": "$userId.email",
        "lang": "$userId.lang",
        "items": 1 // Include other fields as needed
      }
    }
    let myorderscart = await OrdersCart.aggregate(myquery);
    
    */



    // Optionally use toArray() to convert cursor to array
    return myorderscart;
  } catch (e) {
    console.error('err', e);
    return [];
  }
}

module.exports.deleteOrderById = async function(id) {
  try {
    
    const ris = await OrdersCart.findOneAndDelete({ _id: id });
    return ris;
  } catch (e) {
    console.error('Err', e);
    return null;
  }
}

module.exports.getOrdersCartByUserId = async function (uid, idapp, numorder, filterStatus) {

  try {
    let query = { idapp, deleted: false }
    let myorderscart = null;
    if (numorder > 0) {
      query.numorder = numorder;
    }

    if (uid !== 'ALL' && !!uid) {
      query.userId = uid;
    }

    if (filterStatus) {
      query.status = { $gte: shared_consts.OrderStatus.CHECKOUT_SENT };
    }

    myorderscart = await OrdersCart.getOrdersCartByQuery(query);

    /*transform: function(doc, populated) {
    // Rinomina 'idProduct' a 'product' nei risultati della popolazione
    populated.product = populated.idProduct;
    delete populated.idProduct;
    return populated;
  },*/


    return myorderscart
  } catch (e) {
    console.error('Err:', e);
  }
  // return null;
}


module.exports.updateOrdersCartById = async function(id, newOrdersCart, callback) {
  let query = {
    id,
    deleted: false,
  }
  let mycart = null;
  try {
    mycart = await OrdersCart.find(query);
  } catch (err) {
    console.log('ERR: updateOrdersCartById', err);
    if (err) throw err;
  }

  try {
    //exist cart in databse
    if (mycart && mycart.length > 0) {
      return OrdersCart.findOneAndUpdate(
        { _id: id },
        {
          $set: {
            items: newOrdersCart.items,
            totalQty: newOrdersCart.totalQty,
            totalQtyPreordered: newOrdersCart.totalQtyPreordered,
            totalPrice: newOrdersCart.totalPrice,
            totalPriceCalc: newOrdersCart.totalPriceCalc ? newOrdersCart.totalPriceCalc : newOrdersCart.totalPrice,
            totalPriceIntero: newOrdersCart.totalPriceIntero ? newOrdersCart.totalPriceIntero : newOrdersCart.totalPriceIntero,
            userId: userId,
            status: newOrdersCart.status,
            numorder: newOrdersCart.numorder,
            numord_pers: newOrdersCart.numord_pers,
            note: newOrdersCart.note,
            codice_sconto: newOrdersCart.codice_sconto,
            descr_sconto: newOrdersCart.descr_sconto,
            modify_at: new Date(),
          }
        },
        { new: true },
        callback
      )
    } else {
      //no cart in database
      return newOrdersCart.save(callback)
    }
  } catch (e) {
    console.log('Err updateOrdersCartById', e.message);
  }
}


module.exports.setFieldInOrdersById = async function (objtoset, myOrderCart) {

  try {
    let ris2 = null;
    // Imposta su tutti i singoli prodotti ordinati (Order)
    for (const recitem of myOrderCart.items) {
      ris2 = await Order.findOneAndUpdate(
        { _id: recitem.order._id },
        {
          $set: objtoset
        },
        { new: false }
      )
      // console.log('ris', ris2);
    }

    const ris = await OrdersCart.findOneAndUpdate(
      { _id: myOrderCart._id },
      {
        $set: objtoset
      },
      { new: false }
    )

  } catch (e) {
    console.log('Err', e);
  }

}

module.exports.deleteRecsInOrdersById = async function (myOrderCart) {

  try {
    let ris2 = null;
    // Imposta su tutti i singoli prodotti ordinati (Order)
    for (const recitem of myOrderCart.items) {
      ris2 = await Order.findOneAndDelete({ _id: recitem.order._id })
    }

    const ris = await OrdersCart.findOneAndDelete({ _id: myOrderCart._id })

  } catch (e) {
    console.log('Err', e);
  }

}

module.exports.setConsegnatoById = async function (value, myOrderCart) {

  let objtoset = {
    consegnato: value,
    date_consegnato: new Date(),
  };

  return await OrdersCart.setFieldInOrdersById(objtoset, myOrderCart);

}

module.exports.setPreparatoById = async function (value, myOrderCart) {

  let objtoset = {
    preparato: value,
    date_preparato: new Date(),
  };

  return await OrdersCart.setFieldInOrdersById(objtoset, myOrderCart);

}

module.exports.setSpeditoById = async function (value, myOrderCart) {

  let objtoset = {
    spedito: value,
    date_spedito: new Date(),
  };

  return await OrdersCart.setFieldInOrdersById(objtoset, myOrderCart);

}

module.exports.setPagatoById = async function (value, myOrderCart) {

  let objtoset = {
    pagato: value,
    date_pagato: new Date(),
  };

  if (!value) {
    objtoset.date_pagato = null;
  }

  return await OrdersCart.setFieldInOrdersById(objtoset, myOrderCart);

}

module.exports.setConsegnatoById = async function (value, myOrderCart) {

  let objtoset = {
    consegnato: value,
    date_consegnato: new Date(),
  };

  return await OrdersCart.setFieldInOrdersById(objtoset, myOrderCart);

}

module.exports.setConfermatoById = async function (value, myOrderCart) {

  let objtoset = {
    confermato: value,
    date_confermato: new Date(),
  };

  return await OrdersCart.setFieldInOrdersById(objtoset, myOrderCart);

}

module.exports.setRicevutoById = async function (value, myOrderCart) {

  let objtoset = {
    ricevuto: value,
    date_ricevuto: new Date(),
  };

  return await OrdersCart.setFieldInOrdersById(objtoset, myOrderCart);
}

module.exports.deleteReally = async function (value, myOrderCart) {

  return await OrdersCart.deleteRecsInOrdersById(myOrderCart);
}

module.exports.createOrdersCart = async function (newOrdersCart) {
  return await newOrdersCart.save()
}


module.exports.addOrderToMovement = async function (myOrderCart, usernameStore, groupnameStore, req) {

  try {
    if (myOrderCart) {
      const mymov = await Circuit.addMovementByOrdersCart(myOrderCart, usernameStore, groupnameStore);
      return mymov;
    }

    return null;

  } catch (e) {
    console.error('Err', e);
  }
}

module.exports.checkQtaIfIsLow_SendAlert = async function (idapp, idProduct) {
  try {
    const telegrambot = require('../telegram/telegrambot');

    const isLow = await Product.isLowQuantityInStockById(idProduct);
    const instock = await Product.getInStockById(idProduct);
    const myprod = await Product.getProductById(idProduct);
    if (isLow && myprod) {
      let msg = `Il Prodotto '${myprod.productInfo.name}' è rimasto a ${instock} quantità !`;

      await telegrambot.sendMsgTelegramToTheManagers(idapp, msg);

    }
  } catch (e) {
    console.error('Err;', e);
  }
}

module.exports.updateMagazzinoOrdineInLavorazione = async function (idorderscart) {

  try {

    const myorderscart = await OrdersCart.findOne({ _id: idorderscart }).populate('items.order').lean();

    if (myorderscart) {
      for (const idkey in myorderscart.items) {
        let order = myorderscart.items[idkey].order;

        if (!order.confermato) { // Se ancora non è stato confermato:
          let update = {
            $inc: {
              bookedQtyOrdered: order.quantity,
            }
          };
          await Product.findOneAndUpdate({ _id: order.idProduct }, update, { new: false });

          update = {
            $inc: {
              bookedGASQtyOrdered: order.quantitypreordered,
            }
          };
          await Product.findOneAndUpdate({ _id: order.idProduct }, update, { new: false });

          await OrdersCart.checkQtaIfIsLow_SendAlert(myorderscart.idapp, order.idProduct)
        }

      }
    }
  } catch (e) {
    console.error('Err', e);
  }

}


module.exports.updateStockQtaDalMagazzinoOrdineConfermato = async function (idorderscart) {

  try {

    const myorderscart = await OrdersCart.findOne({ _id: idorderscart }).populate('items.order').lean();
    if (myorderscart) {
      for (const idkey in myorderscart.items) {
        let order = myorderscart.items[idkey].order;

        if (!order.confermato) { // Se ancora non è stato confermato:
          let update = {
            $inc: {
              stockQty: -order.quantity,
              stockBloccatiQty: order.quantity,
              bookedQtyConfirmed: order.quantity,
            }
          };
          await Product.findOneAndUpdate({ _id: order.idProduct }, update, { new: false });

          update = {
            $inc: {
              maxbookableGASQty: -order.quantitypreordered,
              bookableGASBloccatiQty: order.quantitypreordered,
              bookedGASQtyConfirmed: order.quantitypreordered,
            }
          };
          await Product.findOneAndUpdate({ _id: order.idProduct }, update, { new: false });
        }

      }
    }
  } catch (e) {
    console.error('Err', e);
  }

}
module.exports.updateStockBloccatiQtaDalMagazzinoOrdineConsegnato = async function (idorderscart) {

  try {

    const myorderscart = await OrdersCart.findOne({ _id: idorderscart }).populate('items.order').lean();

    if (myorderscart) {
      for (const idkey in myorderscart.items) {
        let order = myorderscart.items[idkey].order;

        if (!order.consegnato) {
          let update = {
            $inc: {
              stockBloccatiQty: -order.quantity
            }
          };
          await Product.findOneAndUpdate({ _id: order.idProduct }, update, { new: false });
          update = {
            $inc: {
              bookableGASBloccatiQty: -order.quantitypreordered
            }
          };
          await Product.findOneAndUpdate({ _id: order.idProduct }, update, { new: false });
        }

      }
    }
  } catch (e) {
    console.error('Err', e);
  }

}

module.exports.updateStockQtaPerCancellazioneOrdine = async function (idorderscart) {

  try {

    const myorderscart = await OrdersCart.findOne({ _id: idorderscart }).populate('items.order').lean();

    if (myorderscart) {
      for (const idkey in myorderscart.items) {
        let order = myorderscart.items[idkey].order;
        let update = {};

        let fieldstoUpdate = {};

        if (order.consegnato) {
          // Se l'ordine era stato già Consegnato, allora non fare niente !
          return false;
        } else {

          if (order.confermato) { // Se l'ordine era stato confermato, allora rimetti le Qta in Magazzino
            fieldstoUpdate = {
              ...fieldstoUpdate,
              stockQty: order.quantity,
              stockBloccatiQty: -order.quantity,
              bookedQtyConfirmed: -order.quantity,
            }
          }

          fieldstoUpdate = {
            ...fieldstoUpdate,
            bookedQtyOrdered: -order.quantity,
          }

          update = {
            $inc: fieldstoUpdate,
          };

          await Product.findOneAndUpdate({ _id: order.idProduct }, update, { new: false });
          // --------------

          fieldstoUpdate = {};

          if (order.confermato) { // Se l'ordine era stato confermato, allora rimetti le Qta in Magazzino
            fieldstoUpdate = {
              ...fieldstoUpdate,
              maxbookableGASQty: order.quantitypreordered,
              bookableGASBloccatiQty: -order.quantitypreordered,
              bookedGASQtyConfirmed: -order.quantitypreordered,
            }
          }

          fieldstoUpdate = {
            ...fieldstoUpdate,
            bookedGASQtyOrdered: -order.quantitypreordered,
          }

          update = {
            $inc: fieldstoUpdate,
          };

          await Product.findOneAndUpdate({ _id: order.idProduct }, update, { new: false });
        }
      }

    }

  } catch (e) {
    console.error('Err', e);
  }

}

module.exports.getStorehouseByOrdersCart = function (ordersCart) {

  return ordersCart && ordersCart.items && ordersCart.items.length > 0 && ordersCart.items[0].order.storehouse
    ? ordersCart.items[0].order.storehouse
    : null
}

module.exports.getUsernameStorehouseActual = async function (ordersCart) {

  const storehouse = OrdersCart.getStorehouseByOrdersCart(ordersCart);
  return storehouse
    ? storehouse.username
    : null
}

module.exports.getGroupnameStorehouseActual = async function (ordersCart) {

  const storehouse = OrdersCart.getStorehouseByOrdersCart(ordersCart);
  return storehouse
    ? storehouse.groupname
    : null
}

module.exports.updateCmd = async function (ordersCart, status, value, req, options) {


  let myOrderCart = await OrdersCart.getOrdersCartById(ordersCart._id);
  // let myOrderCart = await OrdersCart.findOne({ _id: ordersCart._id })
  //   .populate('items.order').lean();

  const usernameStore = await OrdersCart.getUsernameStorehouseActual(myOrderCart);
  const groupnameStore = await OrdersCart.getGroupnameStorehouseActual(myOrderCart);

  try {
    if (!!myOrderCart) {

      const id = myOrderCart._id;
      if (status === shared_consts.OrderStatus.CHECKOUT_SENT) {

        if (value) {
          await OrdersCart.updateMagazzinoOrdineInLavorazione(id);
        }

      } else if (status === shared_consts.OrderStatus.ORDER_CONFIRMED) {

        // Aggiorna anche il Magazzino, togliendo le quantità in Stock e aggiungendole su quelle bloccate
        if (value) {
          await OrdersCart.updateStockQtaDalMagazzinoOrdineConfermato(id);
        }
        ris = await OrdersCart.setConfermatoById(value, myOrderCart);

      } else if (status === shared_consts.OrderStatus.PAYED) {

        if (value) {
          if (!myOrderCart.pagato) { // Se ancora non è stato confermato:
            await OrdersCart.addOrderToMovement(myOrderCart, usernameStore, groupnameStore, req);

            ris = await OrdersCart.setPagatoById(value, myOrderCart);
          }
        }

      } else if (status === shared_consts.OrderStatus.PREPARED) {
        ris = await OrdersCart.setPreparatoById(value, myOrderCart);

      } else if (status === shared_consts.OrderStatus.DELIVERED) {  // Consegnato
        if (value) {
          await OrdersCart.updateStockBloccatiQtaDalMagazzinoOrdineConsegnato(id);
        }
        ris = await OrdersCart.setConsegnatoById(value, myOrderCart);
      } else if (status === shared_consts.OrderStatus.SHIPPED) {

        ris = await OrdersCart.setSpeditoById(value, myOrderCart);

      } else if (status === shared_consts.OrderStatus.RECEIVED) {
        ris = await OrdersCart.setRicevutoById(value, myOrderCart);
      } else if (status === shared_consts.OrderStatus.PREPARED) {
        ris = await OrdersCart.setPreparatoById(value, myOrderCart);
      } else if (status === shared_consts.OrderStatus.CANCELED) {
        await OrdersCart.updateStockQtaPerCancellazioneOrdine(id)

      } else if (status === shared_consts.OrderStatus.DELETE_REALLY) {
        await OrdersCart.updateStockQtaPerCancellazioneOrdine(id)
        ris = await OrdersCart.deleteReally(value, myOrderCart);
      }

      if (status !== shared_consts.OrderStatus.DELETE_REALLY) {

        await OrdersCart.setFieldInOrdersById({ status }, myOrderCart);

        myOrderCart = await OrdersCart.getOrdersCartById(ordersCart._id)
      }
      // myOrderCart = await OrdersCart.findOne({ _id: idorderscart });

      return myOrderCart;
    }
  } catch (e) {
    console.error('Err:', e)
  }

}

OrdersCartSchema.pre('save', async function (next) {

  try {
    if (this.isNew) {
      try {
        const myrec = await User.findOne({ idapp: this.idapp }).limit(1).sort({ neworder: -1 });

        if (!!myrec) {
          this.neworder = myrec._doc.neworder + 1;
        } else {
          this.neworder = 1;
        }
      } catch (e) {
        this.neworder = 2;
      }
    }

    next();
  } catch (e) {
    console.error(e.message);
  }
});

module.exports.updateOrdersCartByParams = async function (idOrdersCart, paramstoupdate) {

  const ris = await OrdersCart.findOneAndUpdate({ _id: idOrdersCart }, { $set: paramstoupdate });

  let myorderscart = await OrdersCart.getOrdersCartById(idOrdersCart);

  return myorderscart;
}


module.exports.updateOrdersCartTotals = async function (idOrdersCart, update) {

  try {
    let orderscart = await OrdersCart.getOrdersCartById(idOrdersCart);
    if (orderscart) {

      let newOrdersCart = await CartClass.constructByCart(orderscart);

      await newOrdersCart.updatecarttotals(false);
      await newOrdersCart.updateExtraOrder();

      if (update) {
        await OrdersCart.findOneAndUpdate({ _id: idOrdersCart }, {
          $set: {
            totalPrice: newOrdersCart.totalPrice,
            totalPriceCalc: newOrdersCart.totalPriceCalc,
            totalPriceIntero: newOrdersCart.totalPriceIntero,
            totalQty: newOrdersCart.totalQty,
            note: newOrdersCart.note,
            codice_sconto: newOrdersCart.codice_sconto,
            descr_sconto: newOrdersCart.descr_sconto,
            modify_at: new Date(),
          },
        }
        )
      }

      /*
      for (const order of orderscart.items) {
        await Order.findOneAndUpdate({ _id: order.order._id }, {
          $set: {
            price: order.order.price,
            quantity: order.order.quantity,
            quantitypreordered: order.order.quantitypreordered,
            TotalPriceProduct: order.order.TotalPriceProduct,
          }
        })
      }*/

      orderscart = await OrdersCart.getOrdersCartById(idOrdersCart);

      return orderscart;
    }
  } catch (e) {
    console.error('err', e);
  }
};

module.exports.getmsgorderTelegram = async function (ordersCart) {
  try {
    const statusstr = shared_consts.getStatusStr(ordersCart.status);

    let msg = '🟢✍️ Ordine n. ' + ordersCart.numorder

    msg += '<br>Stato: ' + statusstr;

    msg += '<br>🙎🏻‍♂️ ' + tools.getNomeCognomeEUserNameByUser(ordersCart.user)
    if (ordersCart.note)
      msg += '<br>Note: ' + ordersCart.note;


    msg += '<br><br>Lista Prodotti:'; // 🍊🥑🍋
    for (const ord of ordersCart.items) {
      msg += '<br>';
      let qtystr = ''
      let qtynum = 0
      if (ord.order.quantity > 0)
        qtynum += ord.order.quantity;
      if (ord.order.quantitypreordered > 0)
        qtynum += ord.order.quantitypreordered;

      if (ord.order.product.productInfo.sfuso && ord.order.product.productInfo.weight)
        qtyrisult = qtynum * ord.order.product.productInfo.weight;
      else
        qtyrisult = qtynum + ' x ' + ord.order.product.productInfo.weight;

      qtystr += qtyrisult + ' ' + tools.getUnitsMeasure(ord.order.product.productInfo.unit, true);

      if (ord.order.quantitypreordered > 0)
        qtystr += ' Pre-Ordinati';

      msg += '✅ [' + qtystr + '] ' + ord.order.product.productInfo.name + ' a ' + ord.order.price + '€ ' + (ord.order.after_price ? ord.order.after_price : '') + '<br>Totale = ' + ord.order.TotalPriceProduct.toFixed(2) + '€';
    }

    msg += '<br>';

    let totqta = ordersCart.totalQty + ordersCart.totalQtyPreordered;

    msg += '<br>Totale Prodotti: ' + totqta;
    msg += '<br>Totale Ordine: ' + ordersCart.totalPrice.toFixed(2) + ' € 💰';



    return msg;

  } catch (e) {
    console.error('Err', e);
  }
};

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

