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

async function get (ctx) {
   try {
      const models = ctx.fs.dc.models;
      const { userId, token } = ctx.fs.api
      const { limit, page, orderBy, orderDirection, keyword, forbidden, paraphraseCustom } = ctx.query

      const sequelize = ctx.fs.dc.ORM;
      let findOption = {
         attributes: {
            include: [
               [sequelize.fn('COUNT', sequelize.col('cameraStatusLogs.id')), 'logCount']
            ]
         },
         where: {},
         order: [
            [orderBy || 'id', orderDirection || 'DESC']
         ],
         distinct: true,
         subQuery: false,
         group: [
            'cameraStatus.id',
            'cameraStatusLogs.status_id',
            // 'cameraStatusResolves.id'
         ],
         include: [
            // {
            //    model: models.CameraStatusResolve,
            //    attributes: { exclude: ['statusId'] },
            //    required: false,
            //    duplicating: true
            // },
            {
               model: models.CameraStatusLog,
               attributes: [],
               duplicating: false,
               required: false,
            }
         ],
      }
      if (orderBy) {
         if (orderBy == 'logCount') {
            findOption.order = sequelize.literal(`"logCount" ${orderDirection || 'DESC'}`)
         }
      }
      if (limit) {
         findOption.limit = limit
      }
      if (page && limit) {
         findOption.offset = page * limit
      }
      if (keyword) {
         findOption.where['$or'] = {
            describe: {
               $like: `%${keyword}%`
            },
            paraphrase: {
               $like: `%${keyword}%`
            },
            paraphraseCustom: {
               $like: `%${keyword}%`
            },
         }
      }
      if (forbidden) {
         if (forbidden === 'true') {
            findOption.where.forbidden = true
         } else if (forbidden === 'false') {
            findOption.where.forbidden = false
         }
      }
      if (paraphraseCustom) {
         if (paraphraseCustom === 'true') {
            findOption.where.paraphraseCustom = {
               $or: [{
                  $eq: null
               }, {
                  $eq: ''
               }]
            }
         } else if (paraphraseCustom === 'false') {
            findOption.where.paraphraseCustom = {
               $and: [{
                  $ne: null
               }, {
                  $ne: ''
               }]
            }
         }
      }

      const statusRes = await models.CameraStatus.findAll(findOption)

      delete findOption.order
      delete findOption.limit
      delete findOption.offset
      delete findOption.attributes
      delete findOption.group
      const count = await models.CameraStatus.count(findOption)

      const statusIds = statusRes.map(r => r.id)
      const statusResolveRes = await models.CameraStatusResolve.findAll({
         where: {
            statusId: {
               $in: statusIds
            }
         }
      })

      for (let { dataValues: s } of statusRes) {
         const corResolve = statusResolveRes.filter(r => r.statusId === s.id)
         s.resolve = corResolve
      }

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

async function getSimpleAll (ctx) {
   try {
      const models = ctx.fs.dc.models;
      const statusRes = await models.CameraStatus.findAll({
         attributes: ['id', 'platform', 'status', 'describe'],
      })
      ctx.status = 200;
      ctx.body = statusRes
   } 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.CameraStatus.update({
         forbidden: data.forbidden
      }, {
         where: {
            id: data.statusId
         }
      })

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

async function paraphraseCustom (ctx) {
   try {
      const models = ctx.fs.dc.models;
      const { userId, token } = ctx.fs.api
      const data = ctx.request.body

      await models.CameraStatus.update({
         paraphraseCustom: data.paraphrase,
      }, {
         where: {
            id: { $in: data.statusId }
         }
      })

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

async function resolveEdit (ctx) {
   const transaction = await ctx.fs.dc.orm.transaction();
   try {
      const models = ctx.fs.dc.models;
      const { userId, token } = ctx.fs.api
      const data = ctx.request.body

      await models.CameraStatusResolve.destroy({
         where: {
            statusId: data.statusId
         },
         transaction
      })

      const bulkCreateD = data.resolve.map(r => {
         return {
            statusId: data.statusId,
            resolve: r,
         }
      })
      console.log(bulkCreateD);
      await models.CameraStatusResolve.bulkCreate(bulkCreateD,
         { transaction }
      )

      await transaction.commit();
      ctx.status = 204;
   } catch (error) {
      await transaction.rollback();
      ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);

      console.log('err.name', error.name);
      console.log('err.message', error.message);
      console.log('err.errors', error.errors);

      ctx.status = 400;
      ctx.body = {}
   }
}

async function statusCheck (ctx) {
   try {
      const models = ctx.fs.dc.models;
      const { userId, token } = ctx.fs.api
      const { status, platform, describe } = ctx.query

      if (!status || !platform) {
         throw 'status and platform is required'
      }

      const statusRes = await models.CameraStatus.findOne({
         where: {
            status,
            platform,
         },
         include: [{
            model: models.CameraStatusResolve,
            attributes: { exclude: ['statusId'] },
            required: false,
         }],
      })

      if (!statusRes && describe) {
         await models.CameraStatus.create({
            status, platform, describe
         })
      }

      ctx.status = 200;
      ctx.body = statusRes
   } catch (error) {
      ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
      ctx.status = 400;
      ctx.body = {
         message: typeof error == 'string' ? error : undefined
      }
   }
}

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

      ctx.status = 20;
   } catch (error) {
      ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
      ctx.status = 400;
      ctx.body = {
         message: typeof error == 'string' ? error : undefined
      }
   }
}

module.exports = {
   get,
   getSimpleAll,
   banned,
   paraphraseCustom,
   resolveEdit,
   statusCheck,
   statusRecord,
};