const { body, validationResult } = require('express-validator')
const TicketConversation = require('../models/TicketConversation')
const User = require('../models/User')
const { notifyUser } = require('../WebSocket/controllers/user_EventsController')
const { notifyAdmin } = require('../WebSocket/controllers/admin_EventsController')
const { res404, res500, checkValidations } = require('../plugins/controllersHelperFunctions')
const { _sr } = require('../plugins/serverResponses')
const _faSr = _sr.fa

// env variables
const maxAttachmentSize = 2048
const userIdPopulation = 'first_name last_name verity_businessCode panatech_businessCode'

/// ////////// user
module.exports.add_ticket = [
  [
    body('title').notEmpty().withMessage(_faSr.required.title),
    body('user_id').notEmpty().withMessage('کد مشتری را وارد کنید')
  ],
  checkValidations(validationResult),
  (req, res) => {
    const { title, transaction_id, user_id } = req.body

    const data = { title, transaction_id, user_id }

    const ticketConversation = new TicketConversation(data)
    ticketConversation.save((err, data) => {
      if (err) console.log(err)
      return res.json(data)
    })
  }
]

module.exports.add_message_to_ticket = [
  [
    body('message')
      .if((value, { req }) => !req.files)
      .notEmpty()
      .withMessage(_faSr.required.message)
  ],
  checkValidations(validationResult),
  async (req, res) => {
    const { message } = req.body
    const { user_id } = req

    const data = { message, user_id, isUser: true }

    try {
      // check user scope
      const user = await User.findById(user_id)
      if (user.scope.includes('admin')) data.isUser = false

      // save files
      if (req.files?.image) {
        const image = req.files.image
        const fileName = 'TicketAttachment_' + Date.now() + '.' + image.mimetype.split('/')[1]
        const acceptableFormats = ['png', 'jpg', 'jpeg', 'webp']
        if (!acceptableFormats.includes(image.mimetype.split('/')[1]))
          return res.status(422).json({ validation: { image: { msg: _faSr.format.image } } })
        if (image.size / 1024 > maxAttachmentSize)
          return res
            .status(422)
            .json({ validation: { image: { msg: `حجم تصویر نباید بیشتر از ${maxAttachmentSize} KB باشد.` } } })
        data.image = fileName
        await image.mv(`./static/uploads/images/tickets/${fileName}`)
      }

      // find conversation and update messages
      const conversation = await TicketConversation.findById(req.params.id)
        .populate('user_id', userIdPopulation)
        .populate('messages.user_id', userIdPopulation)
      conversation.messages.push(data)
      await conversation.save()
      if (data.isUser) {
        notifyAdmin('newTicketMsg')
        notifyAdmin('updateUnreadTickets')
      } else {
        notifyUser('updateUnreadTickets', conversation.user_id._id)
        notifyUser('newTicketMsg', conversation.user_id._id)
      }
      return res.json(conversation)
    } catch (e) {
      return res404(res, e)
    }
  }
]

module.exports.get_all_tickets = [
  (req, res) => {
    const { user_id } = req
    TicketConversation.find({ user_id }, (err, conversations) => {
      if (err) return res500(res, err)
      else return res.json(conversations)
    })
  }
]

module.exports.get_one_ticket = [
  (req, res) => {
    TicketConversation.findById(req.params.id)
      .populate('user_id', userIdPopulation)
      .populate('messages.user_id', userIdPopulation)
      .exec((err, data) => {
        if (err) return res404(res, err)
        // after sending messages to user set read status to true
        const messages = data.messages
        setTimeout(async () => {
          try {
            const user = await User.findById(req.user_id)
            if (messages.length) {
              let userNeedsNotify = false
              let adminNeedsNotify = false
              messages.forEach((item, index) => {
                if (item.isUser && user.scope.includes('admin') && !item.read) {
                  // console.log(index, ' these are user messages')
                  adminNeedsNotify = true
                  item.read = true
                }

                if (!item.isUser && !user.scope.includes('admin') && !item.read) {
                  // console.log(index, ' these are admin messages')
                  userNeedsNotify = true
                  item.read = true
                }

                if (index === messages.length - 1) {
                  data.save(err => {
                    if (err) console.log(err)

                    if (userNeedsNotify) notifyUser('updateUnreadTickets', data.user_id._id)

                    if (adminNeedsNotify) notifyAdmin('updateUnreadTickets')
                  })
                }
              })
            }
          } catch (e) {
            return res500(res, e)
          }
        }, 500)
        return res.json(data)
      })
  }
]

/// ///////// admin

module.exports.get_all_tickets_for_admin = [
  (req, res) => {
    TicketConversation.find()
      .sort({created_at: -1})
      .limit(400)
      .populate('user_id', userIdPopulation)
      .exec((err, data) => {
        if (err) return res500(res, err)
        return res.json(data)
      })
  }
]
