'use strict';
const fs = require('fs');
const moment = require('moment')

async function getCameraProject (ctx, next) {
   try {
      const models = ctx.fs.dc.models;
      const { limit, page, orderBy, orderDirection, keyword, abilityId, type, venderId } = ctx.query
      const { userId, token } = ctx.fs.api

      let findOption = {
         attributes: { exclude: ['delete', 'recycleTime',] },
         where: {
            createUserId: userId,
            recycleTime: null,
            delete: false
         },
         order: [
            [orderBy || 'id', orderDirection || 'DESC']
         ],
         include: [{
            model: models.CameraKind
         }]
      }
      let abilityFind = {
         model: models.CameraAbility
      }
      if (limit) {
         findOption.limit = limit
      }
      if (page && limit) {
         findOption.offset = page * limit
      }
      if (keyword) {
         findOption.where.$or = [{
            name: { $like: `%${keyword}%` }
         }, {
            serialNo: { $like: `%${keyword}%` }
         }]
      }
      if (type) {
         findOption.where.type = type
      }
      if (venderId) {
         findOption.where.venderId = venderId
      }
      if (abilityId) {
         abilityFind.where = {
            abilityId: abilityId
         }
      }

      findOption.include.push(abilityFind)
      const cameraRes = await models.Camera.findAll(findOption)
      const total = await models.Camera.count({
         where: findOption.where
      })

      let cameraIds = []
      let createUserIds = new Set()

      for (let c of cameraRes) {
         cameraIds.push(c.dataValues.id)
         createUserIds.add(c.dataValues.createUserId)
      }

      // 查在安心云绑定的数据
      const axbindCameraRes = await ctx.app.fs.axyRequest.get('vcmp/camera/project', { query: { token, cameraId: cameraIds.join(',') } })

      // 查对应创建者信息
      const corUsers = await ctx.app.fs.authRequest.get(`user/${[...createUserIds].join(',') || -1}/message`, { query: { token } })

      for (let { dataValues: camera } of cameraRes) {
         const corBindCamera = axbindCameraRes.find(b => b.cameraId == camera.id)
         if (corBindCamera) {
            camera.station = corBindCamera.stations
         } else {
            camera.station = []
         }
         const corUser = corUsers.find(u => u.id == camera.createUserId)
         if (corUser) {
            camera.createUser = {
               namePresent: corUser.namePresent
            }
         } else {
            camera.createUser = {}
         }
      }

      ctx.status = 200;
      ctx.body = {
         total: total,
         data: cameraRes
      }
   } catch (error) {
      ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
      ctx.status = 400;
      ctx.body = {}
   }
}

async function getCamera (ctx) {
   try {
      const { models } = ctx.fs.dc;
      const { cameraId } = ctx.query

      const cameraRes = await models.Camera.findAll({
         attributes: { exclude: ['delete', 'recycleTime',] },
         where: {
            id: { $in: cameraId.split(',') }
         },
         include: [{
            model: models.CameraAbility
         }, {
            model: models.CameraKind
         }, {
            model: models.Vender
         }]
      })

      ctx.status = 200;
      ctx.body = cameraRes
   } catch (error) {
      ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
      ctx.status = 400;
      ctx.body = {}
   }
}

async function detail (ctx) {
   let errMsg = `获取摄像头详情失败`
   try {
      const { models } = ctx.fs.dc;
      const { cameraId } = ctx.params
      const { userId, token } = ctx.fs.api
      const { utils: { rtmp2others } } = ctx.app.fs

      const cameraRes = await models.Camera.findOne({
         where: {
            id: cameraId
         }
      })

      if (!cameraRes) {
         throw errMsg
      }

      const cameraProject = await ctx.app.fs.axyRequest.get('vcmp/camera/project', { query: { token, cameraId: cameraRes.id } })
      const bindStations = []
      for (let c of cameraProject) {
         for (let s of c.stations) {
            bindStations.push(s)
         }
      }

      const otherUrls = await rtmp2others(cameraRes.rtmp)

      const corUser = await ctx.app.fs.authRequest.get(`user/${cameraRes.createUserId}/message`, { query: { token } })

      ctx.status = 200;
      ctx.body = {
         ...cameraRes.dataValues,
         station: bindStations,
         videoUrl: otherUrls,
         createUser: {
            namePresent: corUser[0].namePresent
         }
      }
   } catch (error) {
      ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
      ctx.status = 400;
      ctx.body = {
         message: errMsg
      }
   }
}

async function getCameraListAll (ctx) {
   try {
      const { models } = ctx.fs.dc;

      const cameraRes = await models.Camera.findAll({
         attributes: ['id', 'name', 'type'],
         where: {
            delete: false,
            recycleTime: null,
         }
      })

      ctx.status = 200;
      ctx.body = cameraRes
   } catch (error) {
      ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
      ctx.status = 400;
      ctx.body = {}
   }
}

async function banned (ctx) {
   try {
      const { models } = ctx.fs.dc;
      const data = ctx.request.body;

      // 向视频服务发送通知

      // 库记录
      await models.Camera.update({
         forbidden: data.forbidden
      }, {
         where: {
            id: data.cameraId
         }
      })

      ctx.status = 204;
   } catch (error) {
      ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
      ctx.status = 400;
      ctx.body = {}
   }
}

async function del (ctx) {
   try {
      const { models } = ctx.fs.dc;
      const { cameraId } = ctx.query
      const { token } = ctx.fs.api

      await models.cameraId.destroy({
         where: {
            id: cameraId
         }
      })

      if (cameraId.length) {
         await ctx.app.fs.axyRequest.delete('vcmp/camera/project', { query: { token, cameraId: cameraId.join(',') } })
      }

      ctx.status = 204;
   } catch (error) {
      ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
      ctx.status = 400;
      ctx.body = {}
   }
}

async function cameraExport (ctx) {
   try {
      const { models } = ctx.fs.dc
      const { userId, token } = ctx.fs.api
      const { utils: { simpleExcelDown } } = ctx.app.fs

      const header = [{
         title: "设备名称",
         key: "name",
      }, {
         title: "设备厂家",
         key: "vender",
      }, {
         title: "接入类型",
         key: "type",
      }, {
         title: "设备状态",
         key: "state",
      }, {
         title: "云台支持",
         key: "cloudControl",
      }, {
         title: "内存卡信息",
         key: "memoryCard",
      }, {
         title: "设备创建时间",
         key: "createTime",
      }, {
         title: "设备添加账号",
         key: "createUser",
      }, {
         title: "项目名称",
         key: "projectName",
      }, {
         title: "pcode",
         key: "pcode",
      }, {
         title: "结构物",
         key: "structure",
      }, {
         title: "测点",
         key: "stationName",
      }, {
         title: "监测因素",
         key: "factor",
      },];

      const cameraRes = await models.Camera.findAll({
         where: {
            createUserId: userId,
            recycleTime: null,
            delete: false
         },
         include: [{
            model: models.CameraAbility
         }, {
            model: models.CameraKind
         }, {
            model: models.Vender
         }]
      })

      let cameraIds = []
      let createUserIds = new Set()

      for (let c of cameraRes) {
         cameraIds.push(c.dataValues.id)
         createUserIds.add(c.dataValues.createUserId)
      }

      // 查在安心云绑定的数据
      const axbindCameraRes = await ctx.app.fs.axyRequest.get('vcmp/camera/project', { query: { token, cameraId: cameraIds.join(',') } })

      // 查对应创建者信息
      const corUsers = await ctx.app.fs.authRequest.get(`user/${[...createUserIds].join(',') || -1}/message`, { query: { token } })

      let exportData = []
      let typeMap = {
         yingshi: '萤石云平台摄像头',
         nvr: 'NVR摄像头',
         ipc: 'IPC 网络摄像头',
         cascade: '不明厂家',
      }
      for (let { dataValues: camera } of cameraRes) {
         camera.vender = camera.vender ? camera.vender.name : ''
         camera.type = typeMap[camera.type]

         const corUser = corUsers.find(u => u.id == camera.createUserId)
         camera.createUser = corUser ? corUser.username : ''

         let stationName = new Set(),
            projectName = new Set(),
            pcode = new Set(),
            structure = new Set(),
            factor = new Set()
         const corBindCamera = axbindCameraRes.find(b => b.cameraId == camera.id)
         if (corBindCamera) {
            for (let station of corBindCamera.stations) {
               stationName.add(station.name)
               factor.add(station.factor.name)
               structure.add(station.structure.name)
               for (let project of station.structure.projects) {
                  projectName.add(project.name)
                  pcode.add(project.url)
               }
            }
         }
         camera.stationName = [...stationName].join('\r\n')
         camera.factor = [...factor].join('\r\n')
         camera.projectName = [...projectName].join('\r\n')
         camera.pcode = [...pcode].join('\r\n')
         camera.structure = [...structure].join('\r\n')

         exportData.push(camera)
      }

      const fileName = `摄像头信息列表_${userId}_${moment().format('YYYYMMDDHHmmss')}` + '.csv'
      const filePath = await simpleExcelDown({ data: exportData, header, fileName: fileName })
      const fileData = fs.readFileSync(filePath);

      ctx.status = 200;
      ctx.set('Content-Type', 'application/x-xls');
      ctx.set('Content-disposition', 'attachment; filename=' + encodeURI(fileName));
      ctx.body = fileData;
   } catch (error) {
      ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
      ctx.status = 400;
      ctx.body = {}
   }
}

async function getAbility (ctx) {
   try {
      const { models } = ctx.fs.dc;

      const abilityRes = await models.CameraAbility.findAll()

      ctx.status = 200;
      ctx.body = abilityRes
   } catch (error) {
      ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
      ctx.status = 400;
      ctx.body = {}
   }
}

async function getKind (ctx) {
   try {
      const { models } = ctx.fs.dc;

      const kindRes = await models.CameraKind.findAll()

      ctx.status = 200;
      ctx.body = kindRes
   } catch (error) {
      ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
      ctx.status = 400;
      ctx.body = {}
   }
}

module.exports = {
   getCameraProject,
   getCamera,
   getCameraListAll,
   detail,
   banned,
   del,
   cameraExport,
   getAbility,
   getKind,
};