const fs = require('fs')
const { body, validationResult } = require('express-validator')
const { res404, res500, checkValidations } = require('../plugins/controllersHelperFunctions')
const { _sr } = require('../plugins/serverResponses')
const _faSr = _sr.fa
// eslint-disable-next-line import/order
const readXlsxFile = require('read-excel-file/node')
const Serial = require('../models/Serials')
const guaranteeSerialsPath = './static/uploads/serials'
const productSerialsPath = './static/uploads/serials_products'

/// // router modules
module.exports.addExel = [
  [
    body('type')
      .notEmpty()
      .withMessage('choose type')
      .bail()
      .custom((value, { rew }) => {
        const validValues = ['guaranteeSerial', 'orginality']
        if (!validValues.includes(value)) return Promise.reject(new Error('invalid type'))
        else return Promise.resolve()
      })
  ],
  checkValidations(validationResult),
  async (req, res) => {
    if (!req.files?.file) return res.status(422).json({ validation: { file: { msg: 'فایل را اضافه کنید' } } })
    if (!req.files?.file.name.split('.').some(item => ['xlsx', 'xltx', 'xlsm', 'xlsb'].includes(item)))
      return res.status(422).json({ validation: { file: { msg: 'فرمت فایل درست نمیباشد' } } })
    const file = req.files.file
    const { type, g } = req.body
    try {
      const exelFile = await readXlsxFile(Buffer.from(file.data))
      const data = await creator(exelFile, type, g, file.name)

      const path = (type === 'guaranteeSerial' ? guaranteeSerialsPath : productSerialsPath) + `/${g}`
      const files = await fs.readdirSync(path)
      for await (const item of files) {
        if (file.name === item) return res.status(422).json({ validation: { file: { msg: 'نام فایل تکراریست' } } })
      }

      await file.mv(`${path}/${file.name}`)

      // res.status(201).json({ msg: _sr.fa.response.success_save, data })
      res.status(201).json(data)
    } catch (err) {
      return res500(res, err)
    }
  }
]

module.exports.getAllExels = [
  (req, res) => {
    const type = req.query?.type
    const g = req.query?.g

    if (!type || !g) {
      res500(res, 'choose type')
    }
    const validValues = ['guaranteeSerial', 'orginality']
    if (!validValues.includes(type)) return res500(res, 'choose type')
    const path = (type === 'guaranteeSerial' ? guaranteeSerialsPath : productSerialsPath) + `/${g}`
    const downloadAblePath = (type === 'guaranteeSerial' ? '/uploads/serials' : '/uploads/serials_products') + `/${g}`
    fs.readdir(path, (err, files) => {
      if (err) return res500(res, err)
      const filesWithURL = files.map(item => {
        return { url: downloadAblePath, name: item }
      })
      return res.json(filesWithURL)
    })
  }
]

module.exports.removeExel = [
  async (req, res) => {
    const type = req.query?.type
    const g = req.query?.g

    if (!type || !g) return res500(res, 'choose type')
    const validValues = ['guaranteeSerial', 'orginality']
    if (!validValues.includes(type)) return res500(res, 'choose type')
    const path = (type === 'guaranteeSerial' ? guaranteeSerialsPath : productSerialsPath) + `/${g}`
    await Serial.deleteMany({ fileName: req.params.name })

    fs.unlink(`${path}/${req.params.name}`, err => {
      if (err) return res404(res, _faSr.not_found.item_id)
      else return res.json({ message: _faSr.response.success_remove })
    })
  }
]

module.exports.checkSerial = [
  [
    body('serial').notEmpty().withMessage('شماره سریال را وارد کنید'),

    body('type')
      .notEmpty()
      .withMessage('choose type')
      .bail()
      .custom((value, { rew }) => {
        const validValues = ['guaranteeSerial', 'orginality']
        if (!validValues.includes(value)) return Promise.reject(new Error('invalid type'))
        else return Promise.resolve()
      })
  ],
  checkValidations(validationResult),
  async (req, res) => {
    try {
      const { serial, type, g } = req.body
      const code = serial.toString().trim().toLowerCase()
      console.log(code)

      const serialStatus = await Serial.findOne({
        code,
        type,
        kind: g
      })
      console.log(serialStatus)
      if (!serialStatus) {
        res404(res, 'این کد در سامانه وجود ندارد')
      } else {
        res.status(200).json({ message: serialStatus.message })
      }
    } catch (e) {
      console.log(e)
      return res500(res, e)
    }
  }
]

const creator = (exel, type, g, name) => {
  return new Promise(async (resolve, reject) => {
    try {
      for (const row of exel) {
        // eslint-disable-next-line no-constant-condition
        const code = row[1].toString().trim().toLowerCase()
        const serial = await Serial.findOne({ code, type, kind: g })
        if (serial) {
          console.info('Repeated serial => ', row[1])

          serial.model = row[0]
          serial.message = row[2]
          serial.type = type
          serial.kind = g
          serial.fileName = name
          serial.save()
        } else {
          console.log('inserting new =>', row[1])
          await Serial.create({
            code,
            model: row[0],
            message: row[2],
            type,
            fileName: name,
            kind: g
          })
        }
      }
      resolve('end')
    } catch (error) {
      console.log(error)

      reject(error.message)
    }
  })
}
