class BaseCrud {
  constructor(model) {
    this.model = model;
  }

  async save(changes) {
    this.logger.debug({ data: { changes } }, `Saving ${this.model}.`);
    return this.model.create(changes);
  }

  async update(id, changes) {
    this.logger.debug({ data: { changes } }, `Updating ${this.model} with id: ${id}`);

    const client = await this.getById(id);

    if (!client) throw new Error(`Update failed! Client does not exists. ClientId : ${id}`);

    Object.keys(changes).forEach((key) => {
      client[key] = changes[key];
    });

    await client.save();

    return client;
  }

  async getById(id, include) {
    this.logger.debug({ data: { id } }, `Retrieving a client by id`);
    // return this.model.findByPk(id); // maybe this can boost performance but we lose inclusion. need to dig into docs
    return this.model.findOne({
      where: { id },
      include,
    });
  }

  async getList(filters = {}, include) {
    this.logger.debug({ data: { filters } }, `Retrieving the list of ` + this.model);

    let { _limit, _offset, ...restFilters } = filters;

    _limit = parseInt(_limit, 10) || 10;
    _offset = parseInt(_offset, 10) || 0;

    return this.model.findAll({
      where: restFilters,
      limit: _limit,
      offset: _offset,
      include,
    });
  }
}

module.exports = BaseCrud;
