const moment = require('moment-jalaali')
const { body, validationResult } = require('express-validator')
const GuaranteeReport = require('../models/GuaranteeReport')
const { _sr } = require('../plugins/serverResponses')
const {
  res404,
  res406,
  res500,
  checkValidations,
  generateRandomDigits
} = require('../plugins/controllersHelperFunctions')
const { SMS } = require('../plugins/SMS_Module')
const { notifyAdmin } = require('../WebSocket/controllers/admin_EventsController')
const _faSr = _sr.fa

// date formaters
function ArpaDateFormat(date) {
  return moment(date).format('YYYY-MM-DD HH:mm:ss')
}

function SmsDateFormat(date) {
  return moment(date).format('jYYYY/jMM/jDD')
}

/// ///////////////// agent
module.exports.add_guaranteeReport = [
  async (req, res) => {
    try {
      const { user_id, agent_id } = req
      const thisTime = Date.now()

      const data = {
        user_id,
        agent_id,
        createDate: ArpaDateFormat(thisTime)
      }

      const gr = GuaranteeReport(data)
      await gr.save()
      return res.json({ message: _faSr.response.success_save })
    } catch (e) {
      return res500(res, e)
    }
  }
]

module.exports.add_report_to_gr = [
  [
    body('customerTel').notEmpty().withMessage('شماره تماس مشتری را وارد کنید'),

    body('ItemName').notEmpty().withMessage('نام کالا را مشخص کنید'),

    body('ItemID').notEmpty().withMessage('Include ItemID'),

    body('ItemCode').notEmpty().withMessage('Include ItemCode'),

    body('productIssue').notEmpty().withMessage('ایراد کالا را وارد کنید'),

    body('usedPieces').notEmpty().withMessage('قطعات مصرفی را وارد کنید'),

    body('recieveDate').notEmpty().withMessage('تاریخ دریافت از مشتری را مشخص کنید'),

    body('deliverDate')
      .notEmpty()
      .withMessage('تاریخ تحویل به مشتری را مشخص کنید')
      .bail()
      .custom((value, { req }) => {
        function timeStamp(date) {
          return Number(moment(date).format('x'))
        }
        const start = timeStamp(req.body.recieveDate)
        const end = timeStamp(value)
        if (end < start)
          return Promise.reject(new Error('تاریخ تحویل به مشتری نباید از تاریخ دریافت از مشتری کوچکتر باشد'))
        else return true
      })
  ],
  checkValidations(validationResult),
  async (req, res) => {
    try {
      const grId = req.params?.grId
      const {
        customerName,
        customerTel,
        ItemName,
        SerialNo1,
        ItemID,
        ItemCode,
        productIssue,
        usedPieces,
        recieveDate,
        deliverDate
      } = req.body

      const data = {
        customerName,
        customerTel,
        ItemName,
        SerialNo1,
        ItemID,
        ItemCode,
        productIssue,
        usedPieces,
        recieveDate,
        deliverDate
      }

      const gr = await GuaranteeReport.findById(grId)
      gr.items.push(data)
      await gr.save()
      return res.json({ message: _faSr.response.success_save })
    } catch (e) {
      return res404(res, e)
    }
  }
]

module.exports.remove_report_from_gr = [
  async (req, res) => {
    try {
      const reportItemId = req.params?.reportItemId
      if (!reportItemId) throw new Error('invalid id')
      const gr = await GuaranteeReport.findOne({ 'items._id': reportItemId })
      gr.items.id(reportItemId).remove()
      await gr.save()
      return res.json({ message: _faSr.response.success_remove })
    } catch (e) {
      return res500(res, e)
    }
  }
]

module.exports.update_gr_description = [
  (req, res) => {
    const { description } = req.body
    const data = {
      description
    }
    GuaranteeReport.findByIdAndUpdate(req.params?.id, data, (err, oldData) => {
      if (err) return res404(res, 'invalid id')
      return res.json({ message: _faSr.response.success_save })
    })
  }
]

module.exports.get_all_gr_for_agent = [
  (req, res) => {
    const { agent_id } = req
    GuaranteeReport.find({ agent_id }, (err, data) => {
      if (err) return res500(res, err)
      else return res.json(data)
    })
  }
]

module.exports.get_one_gr_for_agent = [
  (req, res) => {
    GuaranteeReport.findById(req.params?.id)
      .populate(
        'agent_id',
        'full_name province_name city_name address agent_code postal_code tel_number fax_number mobile_number'
      )
      .exec((err, data) => {
        if (err || !data) return res404(res, err)
        else return res.json(data)
      })
  }
]

module.exports.delete_gr = [
  async (req, res) => {
    try {
      const gr = await GuaranteeReport.findById(req.params?.id)
      if (gr.status !== 'temp') return res406(res, 'نمیتوانید درخواست ارسال شده را حذف کنید')
      await gr.remove()
      return res.json({ message: _faSr.response.success_remove })
    } catch (e) {
      return res404(res, 'invalid id')
    }
  }
]

module.exports.change_gr_status_to_sent_by_agent = [
  async (req, res) => {
    try {
      const thisTime = Date.now()

      const gr = await GuaranteeReport.findById(req.params?.id).populate('agent_id')
      if (!gr) throw new Error('invalid gr id')
      const totalGr = await GuaranteeReport.find({ status: { $ne: 'temp' } })

      if (gr.status !== 'temp') return res406(res, 'این فرم قبلا برای آسان سرویس ارسال شده')
      if (!gr.items.length) return res406(res, 'هیچ آیتمی ای به فرم اضافه نکرده اید')

      // generate tracking code
      const trackingCode = 'GR' + totalGr.length.toString().padStart(4, '0') + generateRandomDigits(2)

      // modify gr
      gr.status = 'sent'
      gr.trackingCode = trackingCode
      gr.sendDate = ArpaDateFormat(thisTime)

      // send sms for agent
      const smsMsg = [
        ' نماینده گرامی فرم گزارش عملکرد گارانتی شما در تاریخ ',
        SmsDateFormat(thisTime),
        ' با کد پیگیری ',
        trackingCode,
        ' برای شرکت ارسال شد. '
      ]

      SMS([gr.agent_id.mobile_number], smsMsg.join(''))

      await gr.save()
      notifyAdmin('updateNewGuaranteeReports')
      return res.json({ message: 'فرم گزارش عملکرد گارانتی ارسال شد' })
    } catch (e) {
      console.log(e)

      return res404(res, e)
    }
  }
]

/// ///////////////// admin
module.exports.get_all_gr_for_admin = [
  async (req, res) => {
    try {
      const grList = await GuaranteeReport.find({ status: { $ne: 'temp' } }).populate(
        'agent_id',
        'full_name agent_code mobile_number national_code province_name city_name province_id city_id'
      )
      return res.json(grList)
    } catch (e) {
      return res500(res, e)
    }
  }
]

module.exports.get_one_gr_for_admin = [
  async (req, res) => {
    try {
      const { user_id } = req
      const gr = await GuaranteeReport.findById(req.params?.id)
        .populate(
          'agent_id',
          'agent_code full_name mobile_number fax_number tel_number province_name city_name national_code address postal_code store_name'
        )
        .populate('_openedBy', 'username first_name last_name')
        .populate('_updatedBy', 'username first_name last_name')
      if (!gr.seen) {
        gr._openedBy = user_id
        gr.seen = true
        await gr.save()
        notifyAdmin('updateNewGuaranteeReports')
      }
      return res.json(gr)
    } catch (e) {
      return res500(res, e)
    }
  }
]

// module.exports.change_gr_status_by_admin = [
// 	[
// 		body('status')
// 			.notEmpty()
// 			.withMessage('status is required')
// 			.bail()
// 			.custom((value, { req }) => {
// 				acceptablvalues = ['waiting', 'delivered']
// 				if (!acceptablvalues.includes(value)) return Promise.reject('invalid status')
// 				else return true
// 			})
// 	],
// 	checkValidations(validationResult),
// 	async (req, res) => {
//    const { user_id } = req
// 		const { status, deliveryCode } = req.body
// 		const thisTime = Date.now()

// 		try {
// 			const gr = await GuaranteeReport.findById(req.params?.id).populate('agent_id')
// 			if (!gr) throw 'invalid gr id'

// 			// check statuses
// 			const statusErrMsg = 'invalid status for this time'
// 			if (gr.status === 'delivered') return res406(res, statusErrMsg)
// 			if (gr.status === 'waiting' && status === 'waiting') return res406(res, statusErrMsg)

// 			// save status
//      gr._updatedBy = user_id
// 			gr.status = status
// 			gr.statusHistory.push({ status: status, date: thisTime })

// 			let smsMessage
// 			// differenet status methods
// 			if (status === 'waiting') {
// 				smsMessage = [
// 					' نماینده گرامی درخواست قطعه شما با کد پیگیری ',
// 					gr.trackingCode,
// 					' در تاریخ ',
// 					SmsDateFormat(thisTime),
// 					' در انتظار قطعه میباشد. '
// 				]
// 			}

// 			if (status === 'delivered') {
// 				if (deliveryCode) gr.deliveryCode = deliveryCode

// 				function deliveryCodePhrase() {
// 					if (deliveryCode.length) return `کد پیگیری مرسوله: ${deliveryCode}` + '\n'
// 					else return ''
// 				}

// 				smsMessage = [
// 					' نماینده گرامی درخواست قطعه شما با کد پیگیری ',
// 					gr.trackingCode,
// 					' در تاریخ ',
// 					SmsDateFormat(thisTime),
// 					' تحویل شد. ',
// 					'\n',
// 					deliveryCodePhrase()
// 				]
// 			}

// 			await SMS([gr.agent_id.mobile_number], smsMessage.join(''))
// 			await gr.save()
// 			return res.json({ message: _faSr.response.success_save })
// 		} catch (e) {
// 			return res500(res, e)
// 		}
// 	}
// ]
