import { Client } from './Client';
import 'mocha';
import { PinusWSClient } from 'pinus-robot-plugin';
import { expect } from 'chai';
import { checkDisplayItems, checkSuccessResponse } from './CheckPatten';
import { COM_TEAM_STATUS, DEBUG_MAGIC_WORD, DEFAULT_HEROES, MSG_TYPE, PUSH_ROUTE } from '../app/consts';

/**
 * @description 组队后的战斗过程：队长开战 -> 设置阵容 -> 对默认敌人造成伤害 -> 获取战斗状态 -> 结算
 * @param {PinusWSClient} capClient
 * @param {string} teamCode
 * @param {Mocha.Done} done
 */
function comBattleProcess(capClient: PinusWSClient, teamCode: string, done: Mocha.Done) {
  capClient.request('battle.comBattleHandler.startBattle', { teamCode }, (startRes) => {
    checkSuccessResponse(startRes, false);
    capClient.request('battle.comBattleHandler.setupHeroes', { teamCode, heroes: DEFAULT_HEROES}, (setupRes) => {
      checkSuccessResponse(setupRes, false);
      const bossHurts = [2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018].map(value => {return {dataId: value, hurtHp: -10000}});
      capClient.request('battle.comBattleHandler.action', {teamCode, bossHurts, killed: [], curRound: 1}, (actionRes) => {
        checkSuccessResponse(actionRes, false);
        capClient.request('battle.comBattleHandler.getComBtlStatus', { teamCode }, (statusRes) => {
          checkSuccessResponse(statusRes);
          expect(statusRes.data.teamInfo).to.be.an('object');
          expect(statusRes.data.teamInfo.status).to.equal(COM_TEAM_STATUS.WIN);
          capClient.request('battle.comBattleHandler.comBattleEnd', { teamCode }, (endRes) => {
            checkSuccessResponse(endRes);
            const { battleGoods, teamInfo, actordata, lv, exp, kingExp} = endRes.data;
            checkDisplayItems(battleGoods);
            expect(teamInfo).to.be.an('object');
            expect(actordata).to.be.an('array');
            expect(lv).to.be.a('number');
            expect(exp).to.be.a('number');
            expect(kingExp).to.be.a('number');
            done();
          });
        });
      });
    })
  });
}

describe('寻宝创建队伍', function() {
  let pinusClient: PinusWSClient;
  let pinusClientT: PinusWSClient; // 用做测试队友
  let roleInfo;
  let roleInfoT;

  const createTeamParms = {blueprtId: 33001, pub: true, ceLimit: 0};
  const searchTeamParms = {lv: [1], magicWord: DEBUG_MAGIC_WORD};

  beforeEach(function(done) {
    const c = new Client();
    const cT = new Client('13121622738');
    const timer = setInterval(async () => {
      if (c.client && cT.client) {
        pinusClient = c.client;
        roleInfo = c.roleInfo;
        pinusClientT = cT.client;
        roleInfoT = cT.roleInfo;
        clearInterval(timer);
        // 创建寻宝队伍有等级限制，最小20级，把玩家等级调整到20级
        // battle.comBattleHandler.searchTeam 需要在searchTeam之前调整
        // comBattle中有多个位置需要设置，索性这里操作一次
        await debugSetRoleLv(pinusClientT);
        await debugSetRoleLv(pinusClient);
        done();
      }
    }, 1000);
  });

  afterEach(function(done) {
    pinusClient.disconnect();
    pinusClientT.disconnect();
    // disconnect 后等待 500ms，供服务器清理环境、退出频道等
    setTimeout(() => {
      done();
    }, 500);
  });

  it('两个玩家匹配到结算', function(done) {
    pinusClient.on('onTeammateAct', (msg) => {
      checkSuccessResponse(msg);
    });
    pinusClient.on('onComBtlStart', (msg) => {
      checkSuccessResponse(msg);
    });
    pinusClient.on('onTeamJoin', (msg) => {
      checkSuccessResponse(msg);
    });
    pinusClient.request('role.heroHandler.addItem', { id: createTeamParms.blueprtId, count: 10 }, res => {
      checkSuccessResponse(res);
      pinusClient.request('battle.comBattleHandler.createTeam', createTeamParms, (res) => {
        checkSuccessResponse(res);
        expect(res.data.teamCode).to.be.a('string');
        expect(res.data.roleStatus).to.be.an('array');
        res.data.roleStatus.forEach(roleSt => {
          expect(roleSt).to.have.all.keys('roleId', 'roleName', 'isCap', 'isFrd', 'head', 'frame', 'spine', 'topLineupCe', 'lv', 'isRobot', 'heroes', 'killed', 'totalDmg', 'frdRatio', 'rewards', 'guildCode', 'sid');
        });
        pinusClientT.request('battle.comBattleHandler.searchTeam', searchTeamParms, (searchRes) => {
          // console.log('searchRes:', searchRes);
          checkSuccessResponse(searchRes, false);
          if (searchRes.data && searchRes.data.teamCode) {
            expect(searchRes.data).to.be.an('object');
            expect(searchRes.data.teamCode).to.be.a('string');
            pinusClientT.request('battle.comBattleHandler.joinTeam', { teamCode: searchRes.data.teamCode, isFrd: false }, (joinRes) => {
              checkSuccessResponse(joinRes);
              if (searchRes.data.teamCode === res.data.teamCode) {
                const { teamCode } = res.data;
                comBattleProcess(pinusClient, teamCode, done);
              } else {
                console.warn('未测试到开战情况');
                done();
              }
            });
          } else {
            console.warn('未测试到匹配成功的情况');
            done();
          }
        });
      });
    });
  });

  it('先搜索再创建队伍的匹配情况', function(done) {
    pinusClientT.request('battle.comBattleHandler.searchTeam', searchTeamParms, (searchRes) => {
      // console.log('searchRes:', searchRes);
      checkSuccessResponse(searchRes, false);
      if (!searchRes.data) {
        pinusClient.request('battle.comBattleHandler.createTeam', createTeamParms, (res) => {
          checkSuccessResponse(res);
          expect(res.data.teamCode).to.be.a('string');
          expect(res.data.roleStatus).to.be.an('array');
          res.data.roleStatus.forEach(roleSt => {
            expect(roleSt).to.have.all.keys('roleId', 'roleName', 'isCap', 'isFrd', 'head', 'frame', 'spine', 'topLineupCe', 'lv', 'isRobot', 'heroes', 'killed', 'totalDmg', 'frdRatio', 'rewards', 'guildCode', 'sid');
          });
          const roleIds = res.data.roleStatus.map(roleSt => { return roleSt.roleId });
          if (roleIds.indexOf(roleInfoT.roleId) === -1) {
            console.warn('未测试到先搜索后招募的组队情况');
            done();
          }
          comBattleProcess(pinusClient, res.data.teamCode, done);
        });
      } else {
        console.warn('未测试到先搜索后招募的组队情况');
        done();
      }
    });
  });

  it('创建队伍并解散', function(done) {
    pinusClient.request('battle.comBattleHandler.createTeam', createTeamParms, (res) => {
      checkSuccessResponse(res);
      expect(res.data.teamCode).to.be.a('string');
      expect(res.data.roleStatus).to.be.an('array');
      res.data.roleStatus.forEach(roleSt => {
        expect(roleSt).to.have.all.keys('roleId', 'roleName', 'isCap', 'isFrd', 'head', 'frame', 'spine', 'topLineupCe', 'lv', 'isRobot', 'heroes', 'killed', 'totalDmg', 'frdRatio', 'rewards', 'guildCode', 'sid');
      });
      pinusClient.request('battle.comBattleHandler.dismiss', {teamCode: res.data.teamCode}, (dismissRes) => {
        expect(dismissRes).to.be.an('object');
        expect(dismissRes.code).equal(0);
        done();
      });
    });
  });

  it('一键邀请消息发送', function(done) {
    let msgReceiveCnt = 0;
    let teamCode = '';
    function checkInviteRes(res) {
      checkSuccessResponse(res);
      expect(JSON.parse(res.data.content).teamCode).to.be.equal(teamCode);
      msgReceiveCnt += 1;
    }
    pinusClientT.on(PUSH_ROUTE.GROUP_MSG, (res) => {
      checkInviteRes(res);
    });
    pinusClient.on(PUSH_ROUTE.GROUP_MSG, (res) => {
      checkInviteRes(res);
    });
    pinusClient.request('battle.comBattleHandler.createTeam', createTeamParms, (res) => {
      checkSuccessResponse(res);
      teamCode = res.data.teamCode;
      expect(teamCode).to.be.a('string');
      expect(res.data.roleStatus).to.be.an('array');
      res.data.roleStatus.forEach(roleSt => {
        expect(roleSt).to.have.all.keys('roleId', 'roleName', 'isCap', 'isFrd', 'head', 'frame', 'spine', 'topLineupCe', 'lv', 'isRobot', 'heroes', 'killed', 'totalDmg', 'frdRatio', 'rewards', 'guildCode', 'sid');
      });
      pinusClient.request('battle.comBattleHandler.autoInvite', {teamCode}, (inviteRes) => {
        checkSuccessResponse(inviteRes, false);
        setTimeout(() => {
          expect(msgReceiveCnt).to.be.greaterThan(0);
          pinusClient.request('battle.comBattleHandler.dismiss', {teamCode}, (dismissRes) => {
            checkSuccessResponse(dismissRes, false);
            done();
          });
        }, 1000);
      });
    });
  });

  it('搜索队伍再取消', function(done) {
    pinusClient.request('battle.comBattleHandler.searchTeam', searchTeamParms, (res) => {
      checkSuccessResponse(res);
      if (!res.data.teamCode) {
        pinusClient.request('battle.comBattleHandler.cancelSearch', {}, (cancelRes) => {
          expect(cancelRes).to.be.an('object');
          expect(cancelRes.code).equal(0);
          done();
        });
      } else {
        expect(res.data).to.be.an('object');
        expect(res.data.teamCode).to.be.a('string');
        done();
      }
    });
  });

  it('查询可招募或助战的次数', function(done) {
    pinusClient.request('battle.comBattleHandler.getComBtlCnt', {}, (res) => {
      checkSuccessResponse(res);
      expect(res.data.assistCnt).to.be.an('number');
      expect(res.data.blueprts).to.be.an('array');
      res.data.blueprts.forEach(item => {
        expect(item.id).to.be.a('number');
        expect(item.count).to.be.a('number');
      });
      done();
    });
  });

  it('获取寻宝记录', function(done) {
    pinusClient.request('battle.comBattleHandler.getTeamRec', {}, (res) => {
      checkSuccessResponse(res);
      expect(res.data.teamInfos).to.be.an('array');
      res.data.teamInfos.forEach(info => {
        expect(info).to.have.contains.keys('teamCode', 'roleIds', 'pub', 'blueprtId', 'lv', 'status', 'roleStatus', 'capId', 'ceLimit', 'roleCnt', 'bossHpArr', 'createdAt');
      });
      done();
    });
  });


  it('组队文字聊天', function(done) {
    let msgReceiveCnt = 0;
    const MSG_CONTENT = 'hello teammate';

    function checkMsg(msg) {
      expect(msg).to.be.an('object');
      expect(msg.content).to.be.equal(MSG_CONTENT);
    }

    pinusClientT.on(PUSH_ROUTE.GROUP_MSG, (res) => {
      checkSuccessResponse(res);
      checkMsg(res.data);
      msgReceiveCnt += 1;
    });
    pinusClient.on(PUSH_ROUTE.GROUP_MSG, (res) => {
      checkSuccessResponse(res);
      checkMsg(res.data);
      msgReceiveCnt += 1;
    });

    pinusClientT.request('battle.comBattleHandler.searchTeam', searchTeamParms, (searchRes) => {
      checkSuccessResponse(searchRes, false);
      if (!searchRes.data) {
        pinusClient.request('battle.comBattleHandler.createTeam', createTeamParms, (res) => {
          checkSuccessResponse(res);
          expect(res.data.teamCode).to.be.a('string');
          expect(res.data.roleStatus).to.be.an('array');
          res.data.roleStatus.forEach(roleSt => {
            expect(roleSt).to.have.all.keys('roleId', 'roleName', 'isCap', 'isFrd', 'head', 'frame', 'spine', 'topLineupCe', 'lv', 'isRobot', 'heroes', 'killed', 'totalDmg', 'frdRatio', 'rewards', 'guildCode', 'sid');
          });
          const roleIds = res.data.roleStatus.map(roleSt => { return roleSt.roleId });
          if (roleIds.indexOf(roleInfoT.roleId) === -1) {
            console.warn('未测试到组队后的聊天');
            done();
          }
          pinusClient.request('battle.comBattleHandler.sendTeamMsg', {teamCode: res.data.teamCode, type: MSG_TYPE.TEXT, content: MSG_CONTENT}, (msgRes) => {
            checkSuccessResponse(msgRes, false);
            setTimeout(() => {
              expect(msgReceiveCnt).to.be.equal(2);
              comBattleProcess(pinusClient, res.data.teamCode, done);
            }, 500);
          });
        });
      } else {
        console.warn('未测试到组队后的聊天');
        done();
      }
    });
  });
});

// debugSetRoleLv - 设置用户等级
async function debugSetRoleLv(client: PinusWSClient) {
  // 更新用户等级 - 范围[20,100]
  const minRoleLv = 20;
  return new Promise((resolve, reject) => {
    client.request('battle.comBattleHandler.debugSetRoleLv', { magicWord: DEBUG_MAGIC_WORD, targetLv: minRoleLv }, (res) => {
      expect(res.data.lv).to.be.equal(minRoleLv);
      if (res.data.lv == minRoleLv) {
        resolve('success');
      } else {
        reject(new Error(`更新 ${res.data.roleId} 失败`));
      }
    })
  })
  
}