const db = require('../db/models');
const Project_audio_tracksDBApi = require('../db/api/project_audio_tracks');
const processFile = require('../middlewares/upload');
const ValidationError = require('./notifications/errors/validation');
const csv = require('csv-parser');
const stream = require('stream');

module.exports = class Project_audio_tracksService {
  static async create(data, currentUser) {
    const transaction = await db.sequelize.transaction();
    try {
      const createdTrack = await Project_audio_tracksDBApi.create(data, {
        currentUser,
        transaction,
      });

      await transaction.commit();
      return createdTrack;
    } catch (error) {
      await transaction.rollback();
      throw error;
    }
  }

  static async bulkImport(req, res) {
    const transaction = await db.sequelize.transaction();

    try {
      await processFile(req, res);
      const bufferStream = new stream.PassThrough();
      const results = [];

      await bufferStream.end(Buffer.from(req.file.buffer, 'utf-8')); // convert Buffer to Stream

      await new Promise((resolve, reject) => {
        bufferStream
          .pipe(csv())
          .on('data', (data) => results.push(data))
          .on('end', async () => {
            console.log('CSV results', results);
            resolve();
          })
          .on('error', (error) => reject(error));
      });

      await Project_audio_tracksDBApi.bulkImport(results, {
        transaction,
        ignoreDuplicates: true,
        validate: true,
        currentUser: req.currentUser,
      });

      await transaction.commit();
    } catch (error) {
      await transaction.rollback();
      throw error;
    }
  }

  static async update(data, id, currentUser) {
    const transaction = await db.sequelize.transaction();
    try {
      let project_audio_tracks = await Project_audio_tracksDBApi.findBy(
        { id },
        { transaction },
      );

      if (!project_audio_tracks) {
        throw new ValidationError('project_audio_tracksNotFound');
      }

      const updatedProject_audio_tracks =
        await Project_audio_tracksDBApi.update(id, data, {
          currentUser,
          transaction,
        });

      await transaction.commit();
      return updatedProject_audio_tracks;
    } catch (error) {
      await transaction.rollback();
      throw error;
    }
  }

  static async deleteByIds(ids, currentUser) {
    const transaction = await db.sequelize.transaction();

    try {
      await Project_audio_tracksDBApi.deleteByIds(ids, {
        currentUser,
        transaction,
      });

      await transaction.commit();
    } catch (error) {
      await transaction.rollback();
      throw error;
    }
  }

  static async remove(id, currentUser) {
    const transaction = await db.sequelize.transaction();

    try {
      await Project_audio_tracksDBApi.remove(id, {
        currentUser,
        transaction,
      });

      await transaction.commit();
    } catch (error) {
      await transaction.rollback();
      throw error;
    }
  }
};
