const moment = require('moment')

module.exports = function (app, opts) {
   const cameraOnlinePush = app.fs.scheduleInit(
      {
         interval: '0 */15 * * * *',
         // interval: '* */1 * * * *',
         // interval: '*/5 * * * * *',
         immediate: false,
         proRun: true,
      },
      async () => {
         try {
            const { models, ORM: sequelize } = app.fs.dc
            const { pushBySms, pushByEmail } = app.fs.utils
            const configRes = await models.CameraStatusPushConfig.findAll({
               where: {
                  forbidden: false
               },
               include: [
                  {
                     model: models.CameraStatusPushMonitor,
                     attributes: ['cameraId'],
                     required: false,
                     duplicating: true
                  },
                  {
                     model: models.CameraStatusPushReceiver,
                     attributes: ['receiver'],
                     duplicating: false,
                     required: false,
                  },
               ],
            })

            const timeNow = moment().startOf('minute').format()
            for (let c of configRes) {
               console.log('上下线推送方式', c.pushWay,);
               // 查配置信息所对应的摄像头15min内的在离线状态
               const cameraIds = c.cameraStatusPushMonitors.map(m => m.cameraId)
               const offlineStatusRes = await models.CameraStatusOfflineLog.findAll({
                  where: {
                     cameraId: { $in: cameraIds },
                     // !!! 時間限制
                     time: {
                        $between: [moment(timeNow).subtract(15, 'minutes').format(), timeNow]
                     }
                  },
                  include: [{
                     model: models.Camera,
                     attributes: ['name']
                  }],
                  order: [['time', 'ASC']],
               })
               console.log('上下线推送路线记录', offlineStatusRes);
               if (offlineStatusRes.length) {
                  const cameraStatusMap = {}
                  // 当前逻辑
                  // 只要最后状态是离线 就做离线推送
                  // 只要出现一次上线 就做上线推送
                  for (let s of offlineStatusRes) {
                     if (cameraStatusMap[s.cameraId]) {
                        cameraStatusMap[s.cameraId].status.push({
                           status: s.status,
                           time: s.time,
                        })
                     } else {
                        cameraStatusMap[s.cameraId] = {
                           status: [{
                              status: s.status,
                              time: s.time,
                           }],
                           cameraId: s.cameraId,
                           name: s.camera.name,
                        }
                     }
                  }
                  let offArr = []
                  let onArr = []
                  for (let k of Object.keys(cameraStatusMap).sort()) {
                     const data = cameraStatusMap[k]
                     if (data.status[0].status == 'OFF') {
                        offArr.push({
                           cameraId: data.cameraId,
                           name: data.name,
                           time: data.status[0].time,
                        })
                     }
                     const onLineIndex = data.status.findIndex(s => s.status == 'ON')
                     if (onLineIndex >= 0) {
                        const onLineLastOffIndex = data.status.findIndex((s, i) => s.status == 'OFF' && i > onLineIndex)
                        // 当前在线记录的上一次离线记录
                        let onlineData = {
                           cameraId: data.cameraId,
                           name: data.name,
                           time: data.status[onLineIndex].time,
                        }
                        if (onLineLastOffIndex >= 0) {
                           onlineData.offTime = data.status[onLineLastOffIndex].time
                        }
                        onArr.push(onlineData)
                     }
                  }

                  // 查当前配置由谁配置
                  const corUser = await app.fs.authRequest.get(`user/${c.createUser}/message`, {
                     query: {
                        // TODO 这里拿不到 token 去鉴权 怎么能系统间鉴权呢
                        // 暂时取消了鉴权系统对这里的判断
                        token: ''
                     }
                  })

                  const receiver = c.cameraStatusPushReceivers.map(r => r.receiver)
                  const logData = {
                     pushConfigId: c.id,
                     receiver: receiver,
                     timing: c.timing,
                     time: moment(timeNow).format(),
                     pushWay: c.pushWay,
                     // camera: cameraIds,
                  }
                  // 离线推送
                  console.log('上下线推送数据', offArr, onArr);
                  console.log('上下线推送接收', receiver);
                  if (offArr.length && c.noticeWay && c.noticeWay.includes('offline') && receiver.length) {
                     if (c.pushWay == 'email') {
                        // 邮件
                        let text = `【${corUser[0].username}】账号下的设备,截止【${moment(timeNow).format('MM月DD日 HH时mm分')}】,新增${offArr.length}个设备掉线:\n`
                        text += offArr.map(o => `【${o.name}】于【${moment(o.time).format('MM月DD日 HH时mm分')}】掉线,`).join('\n')
                        text += `\n请及时处理!`
                        await pushByEmail({
                           email: receiver,
                           title: '尚视设备离线通知',
                           text,
                        })
                        await models.CameraStatusPushLog.create({ ...logData, pushWay: 'email', noticeWay: ['offline'], camera: offArr.map(o => o.cameraId) })
                     } else if (c.pushWay == 'phone') {
                        // 短信
                        let templateParam = {
                           name: `【${corUser[0].username}】`,
                        }
                        let useTempCode = 'SMS_248205074'
                        // let text = `【${corUser[0].username}】账号下的`
                        if (offArr.length == 1) {
                           // text += `【${offArr[0].name}】离线,请及时处理!【${moment(offArr[0].time).format('MM月DD日 HH时mm分')}】`
                           templateParam.deviceName = `【${offArr[0].name}】`
                           templateParam.timeRange = moment(offArr[0].time).format('MM月DD日 HH时mm分')
                        } else {
                           let text = ''
                           text += offArr.map(o => `【${o.name}】`).join('')
                           if (text.length > 35) {
                              text = text.substring(0, 35) + '...'
                              // text += `等${offArr.length}个摄像头离线`
                              templateParam.deviceCount = offArr.length
                              useTempCode = 'SMS_248250074'
                           }
                           templateParam.deviceName = text
                           // text += `,请及时处理!【${moment().format('MM月DD日HH时mm分')}-${moment(timeNow).subtract(15, 'minutes').format('MM月DD日HH时mm分')}】`
                           templateParam.timeRange = `【${moment().format('MM月DD日HH时mm分')} -${moment(timeNow).subtract(15, 'minutes').format('MM月DD日HH时mm分')}】`
                        }
                        await pushBySms({
                           phone: receiver,
                           templateCode: useTempCode,
                           templateParam: templateParam,
                        })
                        await models.CameraStatusPushLog.create({ ...logData, pushWay: 'phone', noticeWay: ['offline'], camera: offArr.map(o => o.cameraId) })
                     }
                  }

                  // 上线推送
                  if (onArr.length && c.noticeWay && c.noticeWay.includes('online') && receiver.length) {
                     if (c.pushWay == 'email') {
                        // 邮件
                        const outTimeCameraOff = onArr.filter(a => !a.offTime)
                        if (outTimeCameraOff.length) {
                           let cameraIds = outTimeCameraOff.map(a => a.cameraId)
                           const lastOfflineRes = await models.CameraStatusOfflineLog.findAll({
                              where: {
                                 cameraId: { $in: cameraIds },
                                 status: 'OFF',
                                 time: {
                                    $lt: moment(timeNow).subtract(15, 'minutes').format()
                                 }
                              },
                              group: ['cameraId'],
                              attributes: ['cameraId', [sequelize.fn('max', sequelize.col('time')), 'time']],
                           })
                           for (let a of onArr) {
                              if (!a.offTime) {
                                 const lastOffline = lastOfflineRes.find(l => l.cameraId == a.cameraId)
                                 if (lastOffline) {
                                    a.offTime = lastOffline.time
                                 }
                              }
                           }
                        }

                        let text = `【${corUser[0].username}】账号下的设备:\n`
                        text += onArr.map(o => `【${o.name}】于【${moment(o.offTime).format('MM月DD日HH时mm分')}】掉线,【${moment(o.time).format('MM月DD日HH时mm分')}】已恢复`).join('\n')
                        await pushByEmail({
                           email: receiver,
                           title: '尚视设备上线通知',
                           text,
                        })
                        await models.CameraStatusPushLog.create({ ...logData, pushWay: 'email', noticeWay: ['online'], camera: onArr.map(o => o.cameraId) })
                     } else if (c.pushWay == 'phone') {
                        // 短信
                        // let text = `【${corUser[0].username}】账号下的`
                        let templateParam = {
                           name: `【${corUser[0].username}】`,
                        }
                        let useTempCode = 'SMS_248250073'
                        if (onArr.length == 1) {
                           // text += `【${onArr[0].name}】已恢复上线,请及时处理!【${moment(onArr[0].time).format('MM月DD日 HH时mm分')}】`
                           templateParam.deviceName = `【${onArr[0].name}】`
                           templateParam.date = moment(onArr[0].time).format('MM月DD日 HH时mm分')
                        } else {
                           let text = ''
                           text += onArr.map(o => `【${o.name}】`).join('')
                           let timeRange = `【${moment().format('MM月DD日HH时mm分')}-${moment(timeNow).subtract(15, 'minutes').format('MM月DD日HH时mm分')}】!`
                           if (text.length > 35) {
                              text = text.substring(0, 35) + '...'
                              // text += `等${onArr.length}个摄像头已恢复上线!`
                              templateParam.deviceCount = onArr.length
                              useTempCode = 'SMS_248120080'
                              templateParam.timeRange = timeRange
                           } else {
                              templateParam.date = timeRange
                           }
                           templateParam.deviceName = text
                        }
                        await pushBySms({
                           phone: receiver,
                           templateCode: useTempCode,
                           templateParam: templateParam,
                        })
                        await models.CameraStatusPushLog.create({ ...logData, pushWay: 'phone', noticeWay: ['online'], camera: onArr.map(o => o.cameraId) })
                     }
                  }
               }
            }
         } catch (error) {
            console.error('15min 上下线推送错误:', error);
         }
      }
   )

   // 摄像头离线定时统计推送
   const cameraOnlineTimingPush = app.fs.scheduleInit(
      {
         interval: '0 */5 * * * *',
         // interval: '*/10 * * * * *', // dev
         immediate: false,
         // immediate: true, // dev
         proRun: true,
      },
      async () => {
         try {
            const { models, ORM: sequelize } = app.fs.dc
            const { pushBySms, pushByEmail } = app.fs.utils
            const timeNow = moment().format()
            const configRes = await models.CameraStatusPushConfig.findAll({
               where: {
                  forbidden: false,
                  noticeWay: {
                     $contains: ['timing']
                  },
                  // !!! 此时此刻
                  timing: moment(timeNow).format('HH:mm')
               },
               include: [
                  {
                     model: models.CameraStatusPushMonitor,
                     attributes: ['cameraId'],
                     required: false,
                     duplicating: true
                  },
                  {
                     model: models.CameraStatusPushReceiver,
                     attributes: ['receiver'],
                     duplicating: false,
                     required: false,
                  },
               ],
            })
            for (let c of configRes) {
               // 查配置信息所对应的摄像头在离线状态
               const cameraIds = c.cameraStatusPushMonitors.map(m => m.cameraId)
               const offlineRes = await models.Camera.findAll({
                  where: {
                     id: { $in: cameraIds },
                  },
                  attributes: ['id', 'name'],
                  include: [{
                     model: models.GbCamera,
                     attributes: ['id', 'online'],
                     required: true,
                     where: {
                        online: 'OFF'
                     }
                  }],
               })

               if (offlineRes.length) {
                  // 查当前配置由谁配置
                  const corUser = await app.fs.authRequest.get(`user/${c.createUser}/message`, {
                     query: {
                        token: ''
                     }
                  })
                  const receiver = c.cameraStatusPushReceivers.map(r => r.receiver)
                  if (receiver.length) {
                     const logData = {
                        pushConfigId: c.id,
                        receiver: receiver,
                        timing: c.timing,
                        time: moment(timeNow).format(),
                        pushWay: c.pushWay,
                        camera: offlineRes.map(o => o.id),
                     }
                     if (c.pushWay == 'email') {
                        // 邮件
                        const offlineTimeRes = await models.CameraStatusOfflineLog.findAll({
                           attributes: ['cameraId', [sequelize.fn('max', sequelize.col('time')), 'time']],
                           where: {
                              cameraId: { $in: offlineRes.map(oc => oc.id) },
                              status: 'OFF',
                           },
                           group: ['cameraId'],
                        })
                        if (offlineTimeRes.length) {
                           let text = `【${corUser[0].username}】账号下的设备,截止${moment(timeNow).format('MM月DD日 HH时mm分')},新增${offlineRes.length}个设备掉线:\n`
                           text += offlineTimeRes.map(o => {
                              let corCamera = offlineRes.find(c => c.id == o.cameraId)
                              if (corCamera) {
                                 return `【${(corCamera || {}).name}】于【${moment(o.time).format('MM月DD日 HH时mm分')}】掉线,`
                              }
                              return ''
                           }).join('\n')
                           text += `\n请及时处理!`
                           await pushByEmail({
                              email: receiver,
                              title: '尚视设备离线定时统计通知',
                              text,
                           })
                           await models.CameraStatusPushLog.create({ ...logData, pushWay: 'email', noticeWay: ['timing'] })
                        }
                     } else if (c.pushWay == 'phone') {
                        // 短信
                        // let text = `【${corUser[0].username}】账号下截止${moment(timeNow).format('YYYY年MM月DD日 HH时')},有${offlineRes.length}个设备掉线,请及时处理!`
                        await pushBySms({
                           phone: receiver,
                           templateCode: 'SMS_248095009',
                           templateParam: {
                              name: corUser[0].username,
                              time: moment(timeNow).format('YYYY年MM月DD日 HH时'),
                              deviceCount: offlineRes.length,
                           },
                        })
                        await models.CameraStatusPushLog.create({ ...logData, pushWay: 'phone', noticeWay: ['timing'] })
                     }
                  }
               }
            }

         } catch (error) {
            console.error(error);
         }
      }
   )

   return {
      cameraOnlinePush,
      cameraOnlineTimingPush,
   }
}