import { Inject, Provide } from '@midwayjs/decorator';
import { BaseService, CoolCommException } from 'midwayjs-cool-core';
import { InjectEntityModel } from '@midwayjs/orm';
import { Repository } from 'typeorm';
import * as _ from 'lodash';
import { ILogger } from '@midwayjs/logger';
import { ShuyouGameTaskEntity } from '../entity/game_task';
import { ShuyouGameTargetEntity } from '../entity/game_target';
import { Utils } from '../../../comm/utils';
import { ShuyouGameCompleteEntity } from '../entity/game_complete';
import { ShuyouGameAgentService } from '../service/game_agent';
import { ShuyouTaskGameRecordEntity } from '../entity/task_game_record';
import { ShuyouLoModeService } from './lo_mode';
import { ShuyouGameDirectorService } from './game_director';
import { ShuyouXJFUtilsService } from './utils_xjf';
import { ShuyouGameDirectorEntity } from '../entity/game_director';
import { ShuyouGameAgentEntity } from '../entity/game_agent';

/**
 * 系统用户
 */
@Provide()
export class ShuyouGameTaskService extends BaseService {
  @InjectEntityModel(ShuyouGameTaskEntity)
  ShuyouGameTaskEntity: Repository<ShuyouGameTaskEntity>;

  @InjectEntityModel(ShuyouGameTargetEntity)
  ShuyouGameTargetEntity: Repository<ShuyouGameTargetEntity>;

  @InjectEntityModel(ShuyouGameCompleteEntity)
  ShuyouGameCompleteEntity: Repository<ShuyouGameCompleteEntity>;

  @InjectEntityModel(ShuyouTaskGameRecordEntity)
  ShuyouTaskGameRecordEntity: Repository<ShuyouTaskGameRecordEntity>;

  @Inject()
  ShuyouGameAgentService: ShuyouGameAgentService;

  @Inject()
  ShuyouLoModeService: ShuyouLoModeService;

  @Inject()
  ShuyouGameDirectorService: ShuyouGameDirectorService;

  @Inject()
  logger: ILogger;

  @Inject()
  utils: Utils;

  @Inject()
  ShuyouXJFUtilsService: ShuyouXJFUtilsService;

  @InjectEntityModel(ShuyouGameDirectorEntity)
  ShuyouGameDirectorEntity: Repository<ShuyouGameDirectorEntity>;

  @InjectEntityModel(ShuyouGameAgentEntity)
  ShuyouGameAgentEntity: Repository<ShuyouGameAgentEntity>;

  /**
   * 重载新增接口
   */
  async add(param) {
    const existsTask = await this.ShuyouGameTaskEntity.findOne({
      id: param.id,
    });
    if (!_.isEmpty(existsTask)) {
      throw new CoolCommException('本平台已存在相同任务id~');
    }
    param.createTime = new Date();
    param.updateTime = new Date();
    // console.log(param)
    let target_new = 0;
    let target_pay = 0;
    let target_active = 0;
    target_new = Math.floor(
      Math.random() *
        (parseInt(param.target_new_high) - parseInt(param.target_new_low) + 1) +
        parseInt(param.target_new_low)
    );
    target_pay = Math.floor(
      Math.random() *
        (parseInt(param.target_pay_high) - parseInt(param.target_pay_low) + 1) +
        parseInt(param.target_pay_low)
    );
    target_active = Math.floor(
      Math.random() *
        (parseInt(param.target_active_high) -
          parseInt(param.target_active_low) +
          1) +
        parseInt(param.target_active_low)
    );
    //
    //此处先创建机房后台的任务
    //机房后台的任务开始=========================
    //先查询出负责人名称与厂商端口名称
    const gameDirectorEntity = await this.ShuyouGameDirectorEntity.findOne({
      id: param.directorId,
    });
    const gameAgentEntity = await this.ShuyouGameAgentEntity.findOne({
      id: param.game_agentId,
    });
    if (_.isEmpty(gameDirectorEntity || gameAgentEntity)) {
      throw new CoolCommException('负责人名称与厂商端口名称错误~');
    }
    const gameDirectorName = gameDirectorEntity.name;
    const gameAgentName = gameAgentEntity.name;
    //
    let xjf_object = {
      date: param.new_date,
      game_id: parseInt(param.id),
      game_name: param.task_name,
      new_target: target_new,
      retained_target: 0,
      pay_target: target_pay,
      pay_price: parseInt(param.target_pay_low), //需要处理
      remark: gameDirectorName,
      spirit_package_name: '0',
      game_package_name: '0',
      game_id_xmy: param.xmy_id,
      sy_data_id: parseInt(param.id),
      new_retained: param.new_retained + '', //需要在数据库添加该字段
      game_url: param.download,
      game_port: gameAgentName,
    };
    //
    let createXJF;
    createXJF = await this.ShuyouXJFUtilsService.createXJF(xjf_object);
    // console.log(createXJF.data)
    if (!_.isEmpty(createXJF) && createXJF.status == 200) {
      param['xjf_id'] = createXJF.data; //获取到机房后台game_id
      // console.log('机房后台game_id' + createXJF.data)
      //机房后台开始游戏
      let startXJF;
      startXJF = await this.ShuyouXJFUtilsService.startXJF(
        parseInt(createXJF.data)
      );
      // console.log(startXJF)
      if (_.isEmpty(startXJF) || startXJF.status != 200) {
        throw new CoolCommException(startXJF.data);
      }
    } else if (!_.isEmpty(createXJF.response)) {
      //抛出具体的返回值
      throw new CoolCommException(createXJF.response.data);
    }
    //机房后台的任务结束=========================
    // 创建游戏目标start==========================
    const existsTarget = await this.ShuyouGameTargetEntity.findOne({
      task_id: param.id,
      new_date: param.new_date,
    });

    if (!_.isEmpty(existsTarget)) {
      // 当天的任务目标已存在,执行更新目标
      let targetValue = {
        task_name: param.task_name,
        updateTime: param.updateTime,
        target_new: target_new,
        target_pay: target_pay,
        target_active: target_active,
        target_new_low: param.target_new_low,
        target_pay_low: param.target_pay_low,
        target_active_low: param.target_active_low,
      };
      // this.logger.info(targetValue)
      await this.ShuyouGameTargetEntity.createQueryBuilder()
        .update()
        .set(targetValue)
        .where('task_id = :task_id and new_date = :new_date', {
          task_id: param.id,
          new_date: param.new_date,
        })
        .execute();
      // this.logger.info(updateResult) //UpdateResult { generatedMaps: [], raw: [], affected: 1 }
      // 执行更新目标
    } else {
      // 添加任务目标
      let targetValue = {
        task_id: param.id,
        task_name: param.task_name,
        directorId: param.directorId,
        new_date: param.new_date,
        createTime: param.createTime,
        updateTime: param.updateTime,
        target_new: target_new,
        target_pay: target_pay,
        target_active: target_active,
        target_new_low: param.target_new_low,
        target_pay_low: param.target_pay_low,
        target_active_low: param.target_active_low,
      };
      // this.logger.info(targetValue)
      await this.ShuyouGameTargetEntity.insert(targetValue);
    }
    // 创建游戏目标end==========================
    // 创建游戏完成game_complete===============================
    const existsComplete = await this.ShuyouGameCompleteEntity.findOne({
      task_id: param.id,
      new_date: param.new_date,
    });
    if (_.isEmpty(existsComplete)) {
      // 添加任务完成game_complete
      let completeObj = {
        task_id: param.id,
        task_name: param.task_name,
        new_date: param.new_date,
        createTime: param.createTime,
        updateTime: param.updateTime,
        complete_new: 0,
        complete_pay: 0,
        complete_active: 0,
      };
      // this.logger.info(completeObj)
      await this.ShuyouGameCompleteEntity.insert(completeObj);
    }
    // 创建游戏目标end==========================
    // 记录端口对应的游戏数量start
    await this.ShuyouGameAgentService.recordGameNum(param.game_agentId);
    // this.logger.info(returnMsg)
    // 记录端口对应的游戏数量end
    await this.updateTaskGame(param);
    return super.add(param);
  }

  /**
   *
   * @param {*} query
   * @return {*}
   * @memberof
   */
  async taskList() {
    const sql = `
        SELECT
          id,
          task_name
        FROM
          shuyou_game_task
        WHERE
          is_run = 1
        order by id
        `;
    return this.nativeQuery(sql);
  }

  /**
   * 重写分页查询
   * @param query
   */
  async page(query) {
    const {
      id,
      task_name,
      is_run,
      login_modeId,
      directorId,
      game_agentId,
      account_typeId,
    } = query;
    const sql = `
            SELECT
            a.id,a.task_name,a.new_date,a.createTime,a.updateTime,a.target_new_low,a.target_new_high,a.target_pay_low,a.target_pay_high,a.target_active_low,a.target_active_high,
            a.lc_two_ratio,a.lc_three_ratio,a.lc_four_ratio,a.lc_five_ratio,a.lc_six_ratio,a.lc_seven_ratio,a.lc_eight_ratio,a.lc_fifteen_ratio,a.lc_thirty_ratio,a.stopTime,
            a.stopRemark,a.new_retained,
            a.remark,a.is_run,a.is_repeat,a.xmy_id,a.qq_channel,a.qq_id,a.mz_channel,a.mz_id,a.download,a.unit_price_low,a.unit_price_high,
            any_value (b.name) AS directorName,b.id AS directorId,
            any_value (c.name) AS login_modeId,
            any_value (d.name) AS game_agentId,
            any_value (e.name) AS account_typeId,
            GROUP_CONCAT(g.game_name) AS gameList
          FROM
            shuyou_game_task a
            LEFT JOIN shuyou_game_director b ON a.directorId = b.id
            LEFT JOIN shuyou_lo_mode c ON a.login_modeId = c.id
            LEFT JOIN shuyou_game_agent d ON a.game_agentId = d.id
            LEFT JOIN shuyou_account_type e ON a.account_typeId = e.id
            LEFT JOIN task_game_record t ON a.id = t.task_id
            LEFT JOIN shuyou_game_list g ON t.game_id = g.id
          WHERE 1 = 1
            ${this.setSql(id, 'and a.id = ?', [id])}
            ${this.setSql(task_name, 'and a.task_name LIKE ?', [
              `%${task_name}%`,
            ])}
            ${this.setSql(is_run == 1 || is_run == 0, 'and a.is_run = ?', [
              is_run,
            ])}
            ${this.setSql(directorId, 'and b.id = ?', [directorId])}
            ${this.setSql(game_agentId, 'and d.id = ?', [game_agentId])}
            ${this.setSql(account_typeId, 'and e.id = ?', [account_typeId])}
            ${this.setSql(login_modeId, 'and c.id = ?', [login_modeId])}
            GROUP BY a.id
        `;
    return this.sqlRenderPage(sql, query);
  }

  /**
   * 根据ID获得信息
   * @param id
   */
  public async info(id) {
    const info = await this.ShuyouGameTaskEntity.findOne({ id });
    const gameIds = await this.nativeQuery(
      'select a.game_id from task_game_record a where a.task_id = ?',
      [id]
    );

    if (info) {
      // delete info.password;
      if (gameIds) {
        info.gameIdList = gameIds.map(e => {
          return parseInt(e.game_id);
        });
      }
    }
    return info;
  }

  /***
   *
   */
  public async infoByGameId(game_id) {
    const info = await this.ShuyouGameTaskEntity.findOne({ xjf_id: game_id });
    // console.log(info);
    return info;
  }

  /**
   * 修改
   * @param param 数据
   */
  async update(param) {
    // console.log(param)
    const new_game_agentId = param.game_agentId;
    const new_login_modeId = param.login_modeId;
    const new_directorId = param.directorId;
    const new_task_name = param.task_name;
    const taskInfo = await this.ShuyouGameTaskEntity.findOne({ id: param.id });
    if (!taskInfo) {
      throw new CoolCommException('任务不存在');
    }
    const xjf_id = taskInfo.xjf_id;
    if (xjf_id != 0) {
      //修改机房后台任务信息开始=========================
      //先查询出负责人名称与厂商端口名称
      const gameDirectorEntity = await this.ShuyouGameDirectorEntity.findOne({
        id: param.directorId,
      });
      const gameAgentEntity = await this.ShuyouGameAgentEntity.findOne({
        id: param.game_agentId,
      });
      if (_.isEmpty(gameDirectorEntity || gameAgentEntity)) {
        throw new CoolCommException('负责人名称与厂商端口名称错误~');
      }
      const gameDirectorName = gameDirectorEntity.name;
      const gameAgentName = gameAgentEntity.name;
      let xjf_object = {
        date: this.utils.formatDate(new Date()),
        game_id: xjf_id,
        game_name: param.task_name,
        new_target: 0,
        retained_target: 0,
        pay_target: 0,
        pay_price: parseInt(param.target_pay_low), //需要处理
        remark: gameDirectorName,
        spirit_package_name: '0',
        game_package_name: '0',
        game_id_xmy: param.xmy_id,
        sy_data_id: parseInt(param.id),
        new_retained: param.new_retained + '',
        game_url: param.download,
        game_port: gameAgentName,
      };
      //
      let queryXjfId;
      queryXjfId = await this.ShuyouXJFUtilsService.queryXjfId(xjf_id);
      let xjfData;
      if (_.isEmpty(queryXjfId) || queryXjfId == -1) {
        xjfData = {
          IdDong: 0,
          IdYang: 0,
        };
      } else {
        xjfData = queryXjfId.data;
      }
      // console.log(xjfData.IdYang)
      // console.log(xjfData.IdDong)
      if (xjfData.IdDong > 0) {
        let updateXJF;
        updateXJF = await this.ShuyouXJFUtilsService.updateXJF(
          xjfData.IdDong,
          xjf_object
        );
        // console.log(updateXJF.data)
        if (
          _.isEmpty(updateXJF) ||
          updateXJF.status != 200 ||
          updateXJF.data != 'OK'
        ) {
          throw new CoolCommException(updateXJF.data);
        }
      }
      //修改机房后台任务信息结束=================================
    }

    const old_game_agentId = taskInfo.game_agentId;
    const old_login_modeId = taskInfo.login_modeId;
    const old_directorId = taskInfo.directorId;
    const old_task_name = taskInfo.task_name;
    await this.ShuyouGameTaskEntity.save(param);
    await this.updateTaskGame(param);
    //检测负责人-厂商-端口，如有变化，则更新对应数量
    if (new_game_agentId != old_game_agentId) {
      await this.ShuyouGameAgentService.recordGameNum(new_game_agentId);
      await this.ShuyouGameAgentService.reduceGameNum(old_game_agentId);
    }
    if (new_login_modeId != old_login_modeId) {
      await this.ShuyouLoModeService.recordGameNum(new_game_agentId);
      await this.ShuyouLoModeService.reduceGameNum(old_game_agentId);
    }
    if (new_directorId != old_directorId) {
      await this.ShuyouGameDirectorService.addGameNumById(new_game_agentId);
      await this.ShuyouGameDirectorService.reduceGameNumById(old_game_agentId);
    }
    //修改当天任务表里的任务名称（当名称变化时）
    if (old_task_name != new_task_name) {
      const existsTarget = await this.ShuyouGameTargetEntity.findOne({
        task_id: param.id,
        new_date: this.utils.formatDate(new Date()),
      });
      if (!_.isEmpty(existsTarget)) {
        // 当天的任务目标已存在,执行更新目标
        let targetValue = {
          task_name: new_task_name,
        };
        // this.logger.info(targetValue)
        await this.ShuyouGameTargetEntity.createQueryBuilder()
          .update()
          .set(targetValue)
          .where('task_id = :task_id and new_date = :new_date', {
            task_id: param.id,
            new_date: this.utils.formatDate(new Date()),
          })
          .execute();
        // this.logger.info(updateResult) //UpdateResult { generatedMaps: [], raw: [], affected: 1 }
      }
    }
  }
  /**
   * 更新任务-游戏关系
   * @param taskGame
   */
  async updateTaskGame(taskGame) {
    await this.ShuyouTaskGameRecordEntity.delete({ task_id: taskGame.id });
    if (taskGame.gameIdList) {
      for (const game_id of taskGame.gameIdList) {
        await this.ShuyouTaskGameRecordEntity.save({
          task_id: taskGame.id,
          game_id,
        });
      }
    }
  }

  /**
   * 删除
   * @param ids
   */
  async delete(ids) {
    let idArr;
    console.log(ids);
    if (ids instanceof Array) {
      idArr = ids;
    } else {
      idArr = ids.split(',');
    }
    for (const id of idArr) {
      //删除游戏时判断游戏是否在数优中，如在，则对应负责人，端口，厂商所属游戏数量-1
      const taskInfo = await this.ShuyouGameTaskEntity.findOne({ id: id });
      if (taskInfo) {
        // console.log(taskInfo)
        if (taskInfo.is_run == 1) {
          await this.ShuyouGameAgentService.reduceGameNum(
            taskInfo.game_agentId
          );
          await this.ShuyouLoModeService.reduceGameNum(taskInfo.login_modeId);
          await this.ShuyouGameDirectorService.reduceGameNumById(
            taskInfo.directorId
          );
        }
      }
      //===================================================================================
      await this.ShuyouTaskGameRecordEntity.delete({ task_id: id });
      await this.ShuyouGameTaskEntity.delete({ id: id });
    }
  }
  /**
   * 根据id删除任务
   * @param id
   */
  async deleteById(id) {
    //===================================================================================
    // console.log(id)
    // console.log(this.utils.formatDate(new Date()))
    //机房后台删除任务============================
    const taskInfo = await this.ShuyouGameTaskEntity.findOne({ id: id });
    if (!taskInfo) {
      throw new CoolCommException('任务不存在');
    }
    const xjf_id = taskInfo.xjf_id;
    if (xjf_id != 0) {
      let queryXjfId;
      queryXjfId = await this.ShuyouXJFUtilsService.queryXjfId(xjf_id);
      let xjfData;
      if (_.isEmpty(queryXjfId) || queryXjfId == -1) {
        xjfData = {
          IdDong: 0,
          IdYang: 0,
        };
      } else {
        xjfData = queryXjfId.data;
      }
      if (xjfData.IdDong > 0) {
        let deleteXJF;
        deleteXJF = await this.ShuyouXJFUtilsService.deleteXJF(xjfData.IdDong);
        // console.log(deleteXJF)
        if (_.isEmpty(deleteXJF) || deleteXJF.status != 200) {
          throw new CoolCommException(deleteXJF.data);
        }
      }
    }
    //=============================================
    await this.ShuyouTaskGameRecordEntity.delete({ task_id: id });
    await this.ShuyouGameTaskEntity.delete({ id: id });
    await this.ShuyouGameTargetEntity.delete({
      task_id: id,
      new_date: this.utils.formatDate(new Date()),
    });
    // await this.ShuyouGameCompleteEntity.delete({ task_id: id, new_date: this.utils.formatDate(new Date()) })
    return 1000;
  }
  //
  /**
   *
   *
   * @param {string} task_id
   * @param {Date} stopTime
   * @param {string} stopRemark
   * @return {*}
   * @memberof ShuyouGameTaskService
   */
  async stopTask(task_id: string, stopTime: Date, stopRemark: string) {
    // const { id_name } = query;
    let obj = {
      id: task_id,
    };
    const ShuyouGameTaskEntity = await this.ShuyouGameTaskEntity.findOne(obj);
    if (ShuyouGameTaskEntity) {
      if (new Date(stopTime).getTime() > new Date().getTime()) {
        ShuyouGameTaskEntity.is_run = 1;
      } else {
        ShuyouGameTaskEntity.is_run = 0;
      }
      ShuyouGameTaskEntity.stopTime = stopTime;
      ShuyouGameTaskEntity.stopRemark = stopRemark;
      // this.logger.info(ShuyouGameTaskEntity)
      await this.ShuyouGameTaskEntity.save(ShuyouGameTaskEntity);
      //机房后台停止游戏=============================
      if (ShuyouGameTaskEntity.xjf_id != 0) {
        let stopXJF;
        stopXJF = await this.ShuyouXJFUtilsService.stopXJF(
          ShuyouGameTaskEntity.xjf_id
        );
        // console.log(stopXJF)
        if (_.isEmpty(stopXJF) || stopXJF.status != 200) {
          throw new CoolCommException(stopXJF.data);
        }
      }
      //=======================================
      return 1000;
    } else {
      return -1;
    }
  }
  /**
   *
   *
   * @param {string} task_id
   * @return {*}
   * @memberof ShuyouGameTaskService
   */
  async startTask(task_id: string) {
    // const { id_name } = query;
    let obj = {
      id: task_id,
    };
    const ShuyouGameTaskEntity = await this.ShuyouGameTaskEntity.findOne(obj);
    if (ShuyouGameTaskEntity) {
      ShuyouGameTaskEntity.is_run = 1;
      ShuyouGameTaskEntity.new_date = new Date(
        this.utils.formatDate(new Date())
      );
      ShuyouGameTaskEntity.stopTime = new Date('2099-01-01');
      ShuyouGameTaskEntity.stopRemark = '';
      // this.logger.info(ShuyouGameTaskEntity)
      await this.ShuyouGameTaskEntity.save(ShuyouGameTaskEntity);
      //机房后台开始游戏=============================
      if (ShuyouGameTaskEntity.xjf_id != 0) {
        let startXJF;
        startXJF = await this.ShuyouXJFUtilsService.startXJF(
          ShuyouGameTaskEntity.xjf_id
        );
        // console.log(startXJF)
        if (_.isEmpty(startXJF) || startXJF.status != 200) {
          throw new CoolCommException(startXJF.data);
        }
      }
      //=======================================
      return 1000;
    } else {
      return -1;
    }
  }

  /**
   * 获取新增账号
   * @param {*} task_id
   * @param {*} account_typeId
   * @return {*}
   * @memberof ShuyouGameTaskService
   */
  async getAccountOne(task_id, account_typeId, account_state) {
    const sql = `
            SELECT
              A.id AS id,
              a.account_text,
              a.password_text,
              a.vpn_text,
              a.manufacturer,
              a.model,
              a.pnumber,
              a.imei,
              a.imsi,
              a.simserial,
              a.androidid,
              a.mac
            FROM
              shuyou_game_account AS A 
            WHERE
              1 = 1
              ${this.setSql(account_typeId, 'and type_id = ?', [
                account_typeId,
              ])}
              AND occupy_taskId = 0 
              ${this.setSql(account_state, 'AND STATUS = ?', [account_state])}
              AND 
                ( SELECT count( 1 ) AS num FROM task_account_record AS T WHERE A.id = T.account_id
                  ${this.setSql(task_id, 'AND T.task_id = ?', [task_id])}
                )= 0 
              AND (
                SELECT
                  count( 1 ) AS num 
                FROM
                  game_account_record AS G 
                WHERE
                  G.game_id IN ( SELECT game_id FROM task_game_record r WHERE 
                    ${this.setSql(task_id, 'r.task_id = ?', [task_id])}
                  ) 
                  AND A.id = G.account_id 
              )= 0 
            ORDER BY
              A.id 
              LIMIT 1
        `;
    return this.nativeQuery(sql);
  }

  /**
   * 获取留存账号
   * @param {*} task_id
   * @param {*} retained_day
   * @return {*}
   * @memberof ShuyouGameTaskService
   */
  async getAccountRetainedOne(task_id, retained_date) {
    const sql = `
        SELECT
          A.id AS id,
          b.account_text AS account_text,
          b.password_text AS password_text,
          b.vpn_text AS vpn_text,
          b.manufacturer AS manufacturer,
          b.model AS model,
          b.pnumber AS pnumber,
          b.imei AS imei,
          b.imsi AS imsi,
          b.simserial AS simserial,
          b.androidid AS androidid,
          b.mac AS mac
        FROM
          task_account_record AS a
          LEFT JOIN shuyou_game_account b ON a.account_id = b.id
        WHERE
          a.statusRetained = 0 AND a.ok_new = 1
          ${this.setSql(task_id, 'AND a.task_id = ?', [task_id])}
          ${this.setSql(retained_date, 'AND a.new_date = ?', [retained_date])}
        ORDER BY
          A.id 
          LIMIT 1
        `;
    return this.nativeQuery(sql);
  }
}
