const BaseCrud = require("./baseCrud");
const VideoShow = require('videoshow');
const Queue = require('../services/queue');

class RobotsService extends BaseCrud {
  constructor(logger, sequelize) {
    super(sequelize.models.Robot);
    this.logger = logger;
    this.sequelize = sequelize;

    const { Brand, Feature, StaffMember, Robot } = this.sequelize.models;
    this.inclusionModel = [
      {
        model: Brand,
        as: "brand",
      },
      {
        model: StaffMember,
        as: "experts",
      },
      {
        model: Feature,
        as: "features",
      },
    ];
  }

  async getList(filters = {}) {
    return super.getList(filters, this.inclusionModel);
  }

  async getById(id) {
    return super.getById(id, this.inclusionModel);
  }

  async update(id, robotInfo) {
    return super.update(id, robotInfo);
  }

  async generateVideo(robot) {
    var voptions = {
      fps: 25,
      transition: false,
      transitionDuration: 0.1, // seconds
      videoBitrate: 1024,
      videoCodec: 'libx264',
      size: '1280x720',
      audioBitrate: '128k',
      audioChannels: 2,
      format: 'mp4',
      pixelFormat: 'yuv420p',
      captionDelay: 10,
      useSubRipSubtitles: false, // Use ASS/SSA subtitles instead 
      subtitleStyle: {
        Fontname: 'Verdana',
        Fontsize: '36',
        PrimaryColour: '16777215',
        SecondaryColour: '11861244',
        TertiaryColour: '11861244',
        BackColour: '-2147483640',
        Bold: '1',
        Italic: '0',
        BorderStyle: '0',
        Outline: '0',
        Shadow: '1',
        Alignment: '2', // left, middle, right
        MarginL: '40',
        MarginR: '40',
        MarginV: '250'
      }
    }

    var images = [{
      path: 'src/assets/black_dot_640_logo.png',
      caption: 'After many years of research and development at Sector Labs',
      loop: 4, // long caption

    },
    {
      path: 'src/assets/black_dot_640_logo.png',
      caption: 'Manufactured by ' + robot.brand.name,
      loop: 4
    },
    {
      path: 'src/assets/black_dot_640_logo.png',
      caption: 'We present to you',
      loop: 3,

    }, {
      path: 'src/assets/black_dot_640_logo.png',
      caption: robot.name,
      loop: 6
    },
    {
      path: 'src/assets/black_dot_640_logo.png',
      caption: 'With total weight ' + robot.weight + ' kg',
      loop: 4
    },
    {
      path: 'src/assets/black_dot_640_logo.png',
      caption: 'Running for ' + robot.autonomy + ' hours before recharge',
      loop: 4
    }];

    robot.features.length && images.push({
      path: 'src/assets/black_dot_640_logo.png',
      caption: 'Unique features',
      loop: 3
    });

    images = images.concat(robot.features.map((f) => {
      return {
        path: 'src/assets/black_dot_640_logo.png',
        caption: f.name,
        loop: 4
      }
    }));


    images = images.concat([
      {
        path: 'src/assets/black_dot_640_logo.png',
        caption: robot.name + " will be great for your " + robot.type,
        loop: 4
      },
      {
        path: 'src/assets/black_dot_640_logo.png',
        caption: "Get one now at the remarkable price of $" + robot.price.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ","),
        loop: 5,
      },
      {
        path: 'src/assets/logo.png',
        loop: 2
      }]);

    this.logger.info("[-] Queueing video generation")
    const filename = `video_${robot.id}.mp4`;

    robot.video = null;
    await robot.save();

    Queue.add('robot_video_' + robot.id, () => {
      this.logger.info("[-] Starting video generation")
      return new Promise((resolve, reject) => {
        VideoShow(images, voptions)
          .audio('src/assets/inspire.mp3')
          .save(`/home/node/videos/${filename}`)
          .on('start', (command) => {
            this.logger.debug('ffmpeg process started:', command)
          })
          .on('error', (err) =>  {
            this.logger.error("[!] Error during video generation! Error:")
            this.logger.error(err);
            reject(err);
          })
          .on('end', () => {
            this.logger.info("[+] Video file generated.")
            resolve()
          })
      }).then(() => {
        robot.video = filename;
        return robot.save();
      });
    });

    Queue.run();
  }
}

module.exports = RobotsService;
