const fs = require('fs')
const mongoose = require('mongoose')
const { body, validationResult } = require('express-validator')
const jimp = require('jimp')
const Learning = require('../models/Learning')
const { _sr } = require('../plugins/serverResponses')
const { res404, res500, checkValidations } = require('../plugins/controllersHelperFunctions')
const _faSr = _sr.fa
//
const coverWidth = 1300
const coverHeight = 620
const thumbWidth = 636
const thumbHeight = 400
const coverQuality = 80
// const coverThumbQuality = 100
const shortDescriptionLength = 260

const paginateLimit = 5

module.exports.create = [
  [
    // title
    body('title')
      .notEmpty()
      .withMessage(_faSr.required.title)
      .custom((value, { req }) => {
        return Learning.findOne({ title: value }).then(post => {
          if (post) return Promise.reject(_faSr.duplicated.title)
          return true
        })
      }),

    // description
    body('description').notEmpty().withMessage(_faSr.required.description),

    // short description
    body('short_description').notEmpty().withMessage(_faSr.required.description)
  ],
  checkValidations(validationResult),
  (req, res) => {
    if (!req.files || !req.files.cover)
      return res.status(422).json({ validation: { cover: { msg: _faSr.required.cover } } })

    const data = {
      _creator: req.user_id,
      title: req.body.title,
      description: req.body.description,
      short_description: req.body.short_description.slice(0, shortDescriptionLength) + ' ... '
    }

    if (req.files && req.files.cover) {
      const cover = req.files.cover

      // validate image format
      const supportedFormats = ['jpg', 'jpeg', 'png', 'webp']
      if (!supportedFormats.includes(cover.mimetype.split('/')[1])) {
        return res.status(422).json({ validation: { cover: { msg: _faSr.format.image } } })
      }

      const coverName = 'blog_' + Date.now() + '.' + cover.mimetype.split('/')[1]
      data.cover = data.thumb = coverName

      jimp
        .read(cover.data)
        .then(img => {
          img
            .cover(coverWidth, coverHeight)
            .quality(coverQuality)
            .write(`./static/uploads/images/blog/${coverName}`)
            .resize(thumbWidth, jimp.AUTO)
            .cover(thumbWidth, thumbHeight)
            .write(`./static/uploads/images/blog/thumb/${coverName}`)
        })
        .catch(err => {
          console.log(err)
        })
    }

    if (req.files && req.files.video) {
      const video = req.files.video

      // validate video format
      const supportedFormats = ['mp4', 'avi', 'wmv']
      if (!supportedFormats.includes(video.mimetype.split('/')[1])) {
        return res.status(422).json({ validation: { video: { msg: _faSr.format.video } } })
      }

      const videoName = 'blog_' + Date.now() + '.' + video.mimetype.split('/')[1]
      data.video = videoName
      video.mv(`./static/uploads/videos/${videoName}`, err => {
        if (err) console.log(err)
      })
    }

    const post = new Learning(data)
    post.save(err => {
      if (err) console.log(err)
      return res.json({ message: _faSr.response.success_save })
    })
  }
]

module.exports.getAll = [
  (req, res) => {
    const page = req.params?.page
    if (page === 'all') {
      Learning.find({}, (err, data) => {
        if (err) return res500(res, err)
        else return res.json(data)
      })
    } else {
      Learning.paginate({}, { page: page || 1, limit: paginateLimit, sort: { _id: -1 } }, (err, data) => {
        if (err) return res500(res, err)
        if (!data.docs.length && Number(req.params.page) !== 1)
          return res.status(404).json({ message: _faSr.not_found.item_id })
        else return res.json(data)
      })
    }
  }
]

module.exports.getOne = [
  (req, res) => {
    const query = {}
    if (mongoose.isValidObjectId(req.params.id)) query._id = req.params.id
    else query.title = req.params.id
    Learning.findOne(query)
      .populate('_creator', 'first_name last_name')
      .exec((err, post) => {
        if (err || !post) return res404(res, err)
        return res.json(post)
      })
  }
]

module.exports.update = [
  [
    // title
    body('title')
      .notEmpty()
      .withMessage(_faSr.required.title)
      .custom((value, { req }) => {
        return Learning.findOne({ title: value }).then(post => {
          if (post && post._id.toString() !== req.params.id) return Promise.reject(_faSr.duplicated.title)
          return true
        })
      }),

    // description
    body('description').notEmpty().withMessage(_faSr.required.description),

    // short description
    body('short_description').notEmpty().withMessage(_faSr.required.description)
  ],
  checkValidations(validationResult),
  (req, res) => {
    const data = {
      _creator: req.user_id,
      title: req.body.title,
      description: req.body.description,
      short_description: req.body.short_description.slice(0, shortDescriptionLength) + ' ... '
    }

    if (req.files && req.files.cover) {
      const cover = req.files.cover

      // validate image format
      const supportedFormats = ['jpg', 'jpeg', 'png', 'webp']
      if (!supportedFormats.includes(cover.mimetype.split('/')[1])) {
        return res.status(422).json({ validation: { cover: { msg: _faSr.format.image } } })
      }

      const coverName = 'blog_' + Date.now() + '.' + cover.mimetype.split('/')[1]
      data.cover = data.thumb = coverName

      jimp
        .read(cover.data)
        .then(img => {
          img
            .cover(coverWidth, coverHeight)
            .quality(coverQuality)
            .write(`./static/uploads/images/blog/${coverName}`)
            .resize(thumbWidth, jimp.AUTO)
            .cover(thumbWidth, thumbHeight)
            .write(`./static/uploads/images/blog/thumb/${coverName}`)
        })
        .catch(err => {
          console.log(err)
        })
    }

    if (req.files && req.files.video) {
      const video = req.files.video

      // validate video format
      const supportedFormats = ['mp4', 'avi', 'wmv']
      if (!supportedFormats.includes(video.mimetype.split('/')[1])) {
        return res.status(422).json({ validation: { video: { msg: _faSr.format.video } } })
      }

      const videoName = 'blog_' + Date.now() + '.' + video.mimetype.split('/')[1]
      data.video = videoName
      video.mv(`./static/uploads/videos/${videoName}`, err => {
        if (err) console.log(err)
      })
    }

    Learning.findByIdAndUpdate(req.params.id, data, (err, oldData) => {
      if (err) return res404(res, err)
      if (req.files && req.files.cover) {
        fs.unlink(`./static/${oldData.cover}`, err => {
          if (err) console.log(err)
        })
        fs.unlink(`./static/${oldData.thumb}`, err => {
          if (err) console.log(err)
        })
      }
      if (req.files && req.files.video && oldData.video)
        fs.unlink(`./static/${oldData.video}`, err => {
          if (err) console.log(err)
        })
      Learning.findById(oldData._id, (err, newData) => {
        if (err) return res404(res, err)
        return res.json(newData)
      })
    })
  }
]

module.exports.delete = [
  (req, res) => {
    Learning.findByIdAndDelete(req.params.id, (err, post) => {
      if (err) return res.status(404).json({ message: err })
      fs.unlink(`./static/${post.cover}`, err => {
        if (err) console.log(err)
      })
      fs.unlink(`./static/${post.thumb}`, err => {
        if (err) console.log(err)
      })
      if (post.video)
        fs.unlink(`./static/${post.video}`, err => {
          if (err) console.log(err)
        })
      return res.json({ message: _faSr.response.success_remove })
    })
  }
]
