import { DEFAULT_MSG_PER_PAGE, MSG_TYPE, PUSH_ROUTE, CHANNEL_PREFIX, DEBUG_MAGIC_WORD, STATUS, HERO_GROW_MAX, ABI_STAGE } from './../app/consts';
import { Client } from './Client';
import 'mocha';
import { PinusWSClient } from 'pinus-robot-plugin';
import { expect } from 'chai';
import { checkSuccessResponse } from './CheckPatten';

const TEXT_MSG = { type: MSG_TYPE.TEXT, content: 'hello' }
const LVBU_HID = 44;
const XIAHOUQINGYI_HID = 53;

function sendPrivateMessageParm(targetRoleInfo, msg) {
  const { roleId: targetRoleId, roleName: targetRoleName } = targetRoleInfo;
  const result = { targetRoleId, targetRoleName, ...msg };
  return result;
}

function sendGroupMessageParm(channel, channelId, msg) {
  const result = { channel, channelId, ...msg };
  return result;
}

function checkGroupMsg(msg, roleId, roomId, content) {
  expect(msg.roleId).to.equal(roleId);
  expect(msg.content).to.equal(content);
  expect(msg.roomId).to.equal(roomId);
}

function checkHeroInfoStr(content: string) {
  expect(content).to.be.a('string');
  const heroInfo = JSON.parse(content);
  expect(heroInfo).to.be.an('object');
  const { roleId, roleName, hero } = heroInfo;
  expect(roleId).to.be.a('string');
  expect(roleName).to.be.a('string');
  const { hid, seqId, hName } = hero;
  expect(hid).to.be.a('number');
  expect(seqId).to.be.a('number');
  expect(hName).to.be.a('string');
}

function testGroupMsg(pinusClient: PinusWSClient, roleInfo: any, pinusClientT: PinusWSClient, channel: string, channelId: string, done: Mocha.Done) {
  let msgReceiveCnt = 0;
  const roomId = `${channel}_${channelId}`;
  pinusClientT.on(PUSH_ROUTE.GROUP_MSG, (res) => {
    checkSuccessResponse(res);
    checkGroupMsg(res.data, roleInfo.roleId, roomId, TEXT_MSG.content);
    msgReceiveCnt += 1;
  });
  pinusClient.on(PUSH_ROUTE.GROUP_MSG, (res) => {
    checkSuccessResponse(res);
    checkGroupMsg(res.data, roleInfo.roleId, roomId, TEXT_MSG.content);
    msgReceiveCnt += 1;
  });
  setTimeout(() => {
    pinusClient.request('chat.chatHandler.sendGroupMessage', sendGroupMessageParm(channel, channelId, TEXT_MSG), (res) => {
      checkSuccessResponse(res, false);
      setTimeout(() => {
        expect(msgReceiveCnt).to.be.equal(2);
        pinusClientT.off(PUSH_ROUTE.GROUP_MSG);
        pinusClient.off(PUSH_ROUTE.GROUP_MSG);
        done();
      }, 2000);
    });
  }, 100);
}

// function testHeroPush(pinusClient: PinusWSClient, pinusClientT: PinusWSClient, hid: number, route: string, routeParam: object, done: Mocha.Done) {
//   let msgReceiveCnt = 0;
//   pinusClientT.on(PUSH_ROUTE.GROUP_MSG, (res) => {
//     checkSuccessResponse(res);
//     checkHeroInfoStr(res.data.content);
//     msgReceiveCnt += 1;
//   });
//   pinusClient.on(PUSH_ROUTE.GROUP_MSG, (res) => {
//     checkSuccessResponse(res);
//     checkHeroInfoStr(res.data.content);
//     msgReceiveCnt += 1;
//   });
//   pinusClient.request('role.heroHandler.testCleanUp', { magicWord: DEBUG_MAGIC_WORD, hid }, (cleanUpRes) => {
//     if (cleanUpRes.code !== STATUS.HERO_NOT_FIND.code) {
//       checkSuccessResponse(cleanUpRes, false);
//     }
//     pinusClient.request(route, routeParam, (composeRes) => {
//       checkSuccessResponse(composeRes);
//       setTimeout(() => {
//         expect(msgReceiveCnt).to.be.equal(2);

//         done();
//       }, 1000);

//     });
//   });
// }

describe('聊天测试', function () {
  let pinusClient: PinusWSClient;
  let pinusClientT: PinusWSClient; // 用做测试队友
  let roleInfo;
  let roleInfoT;

  beforeEach(function (done) {
    const c = new Client();
    const cT = new Client('13121622738');
    const timer = setInterval(() => {
      if (c.client && cT.client) {
        pinusClient = c.client;
        roleInfo = c.roleInfo;
        pinusClientT = cT.client;
        roleInfoT = cT.roleInfo;
        clearInterval(timer);
        done();
      }
    }, 1000);
  });

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

  it('两个玩家互相发送', function (done) {
    pinusClientT.on(PUSH_ROUTE.PRIVATE_MSG, (msg) => {
      checkSuccessResponse(msg);
      expect(msg.data.content).to.equal(TEXT_MSG.content);
    });

    setTimeout(() => {
      pinusClient.request('chat.chatHandler.sendPrivateMessage', sendPrivateMessageParm(roleInfoT, TEXT_MSG), (res) => {
        checkSuccessResponse(res);
        expect(res.data.content).to.equal(TEXT_MSG.content);
        done();
      });
    }, 1000);
  });

  it('获取私聊历史消息', function (done) {
    pinusClient.request('chat.chatHandler.getPrivateMessage', { targetRoleId: roleInfoT.roleId, count: 10 }, (res) => {
      checkSuccessResponse(res);
      expect(res.data.targetRoleId).to.be.a('string');
      expect(res.data.msgs).to.be.an('array');
      res.data.msgs.forEach(msg => {
        // expect(msg.content).to.equal(TEXT_MSG.content);
        expect(msg.content).to.be.a('string');
      });
      done();
    })
  });

  it('最近私聊的用户信息', function () {
    function checkChatInfos(roleInfo) {
      const chatInfos = roleInfo.recentPrivateChats;
      if (!chatInfos) {
        console.warn(`用户${roleInfo.roleName}没有最近的私聊信息`);
        return;
      }
      for (let chatInfo of chatInfos) {
        expect(chatInfo.targetRoleId).to.be.a('string');
        expect(chatInfo.targetRoleName).to.be.a('string');
        expect(Date.parse(chatInfo.lastChatTime)).to.be.a('number');
        expect(Date.parse(chatInfo.lastReadTime)).to.be.a('number');
        expect(chatInfo.unreadCnt).to.be.a('number');
      }
    }
    checkChatInfos(roleInfo);
    checkChatInfos(roleInfoT);
  });

  it('最近群聊的消息', function () {
    function checkMsgs(msgs, roleName) {
      if (!msgs) {
        return;
      }
      expect(msgs).to.be.an('array');
      if (msgs.length === 0) {
        console.log(`用户${roleName}缺少群消息`);
      }
      for (let msg of msgs) {
        expect(msg.roleId).to.be.a('string');
        expect(msg.roleName).to.be.a('string');
        expect(msg.content).to.be.a('string');
        expect(msg.roomId).to.be.a('string');
      }
    }
    function checkAllGroupMsgs(roleInfo) {
      checkMsgs(roleInfo.sysMsgs, roleInfo.roleName);
      checkMsgs(roleInfo.worldMsgs, roleInfo.roleName);
      checkMsgs(roleInfo.guildMsgs, roleInfo.roleName);
    }
    checkAllGroupMsgs(roleInfo);
    checkAllGroupMsgs(roleInfoT);
  });

  it('测试系统频道橙将合成消息', function (done) {
    let msgReceiveCnt = 0;
    pinusClientT.on(PUSH_ROUTE.GROUP_MSG, (res) => {
      checkSuccessResponse(res);
      // checkHeroInfoStr(res.data.content);
      msgReceiveCnt += 1;
    });
    pinusClient.on(PUSH_ROUTE.GROUP_MSG, (res) => {
      checkSuccessResponse(res);
      // checkHeroInfoStr(res.data.content);
      msgReceiveCnt += 1;
    });
    pinusClient.request('role.heroHandler.testCleanUp', { magicWord: DEBUG_MAGIC_WORD, hid: LVBU_HID }, (cleanUpRes) => {
      if (cleanUpRes.code !== STATUS.HERO_NOT_FIND.code) {
        checkSuccessResponse(cleanUpRes, false);
      }
      pinusClient.request('role.heroHandler.compose', { hid: LVBU_HID }, (composeRes) => {
        checkSuccessResponse(composeRes);
        setTimeout(() => {
          expect(msgReceiveCnt).to.be.equal(2);
          pinusClientT.off(PUSH_ROUTE.GROUP_MSG);
          pinusClient.off(PUSH_ROUTE.GROUP_MSG);
          done();
        }, 1000);
      });
    });
  });

  // 材料不足先跳过
  it.skip('测试系统频道升六星消息', function (done) {
    let msgReceiveCnt = 0;
    pinusClientT.on(PUSH_ROUTE.GROUP_MSG, (res) => {
      checkSuccessResponse(res);
      // checkHeroInfoStr(res.data.content);
      msgReceiveCnt += 1;
    });
    pinusClient.on(PUSH_ROUTE.GROUP_MSG, (res) => {
      checkSuccessResponse(res);
      // checkHeroInfoStr(res.data.content);
      msgReceiveCnt += 1;
    });
    pinusClient.request('role.heroHandler.testCleanUp', { magicWord: DEBUG_MAGIC_WORD, hid: XIAHOUQINGYI_HID }, (cleanUpRes) => {
      if (cleanUpRes.code !== STATUS.HERO_NOT_FIND.code) {
        checkSuccessResponse(cleanUpRes, false);
      }
      pinusClient.request('role.heroHandler.compose', { hid: XIAHOUQINGYI_HID }, (composeRes) => {
        checkSuccessResponse(composeRes);
        for (let i = 2; i <= HERO_GROW_MAX.STAR; i++) {
          for (let j = 0; j < ABI_STAGE.END; j++) {
            setTimeout(() => {
              pinusClient.request('role.heroHandler.starUp', { hid: XIAHOUQINGYI_HID, star: i, starStage: j }, (starUpRes) => {
                if (starUpRes.code === STATUS.ROLE_STAR_REACH_MAX.code) {
                  expect(msgReceiveCnt).to.be.equal(2);
                  done();
                } else {
                  checkSuccessResponse(starUpRes);
                }
              });
            }, 50 * (i - 2) * ABI_STAGE.END + 50 * j);
          }
        }
      });
    });
  });

  // 材料不足先跳过
  it.skip('测试系统频道升品消息', function (done) {
    let msgReceiveCnt = 0;
    function checkHeroInfoRes(res) {
      checkSuccessResponse(res);
      // checkHeroInfoStr(res.data.content);
      msgReceiveCnt += 1;
    }
    pinusClientT.on(PUSH_ROUTE.GROUP_MSG, (res) => {
      checkHeroInfoRes(res);
    });
    pinusClient.on(PUSH_ROUTE.GROUP_MSG, (res) => {
      checkHeroInfoRes(res);
    });
    pinusClient.request('role.heroHandler.testCleanUp', { magicWord: DEBUG_MAGIC_WORD, hid: XIAHOUQINGYI_HID }, (cleanUpRes) => {
      if (cleanUpRes.code !== STATUS.HERO_NOT_FIND.code) {
        checkSuccessResponse(cleanUpRes, false);
      }
      pinusClient.request('role.heroHandler.compose', { hid: XIAHOUQINGYI_HID }, (composeRes) => {
        checkSuccessResponse(composeRes);
        for (let i = 2; i <= HERO_GROW_MAX.STAR; i++) {
          for (let j = 0; j < ABI_STAGE.END; j++) {
            setTimeout(() => {
              if (i === HERO_GROW_MAX.STAR && j > 0) {
              } else {
                pinusClient.request('role.heroHandler.starUp', { hid: XIAHOUQINGYI_HID, star: i, starStage: j }, (starUpRes) => {
                  if (starUpRes.code === STATUS.ROLE_STAR_REACH_MAX.code) {
                    pinusClient.request('role.heroHandler.qualityUp', { hid: XIAHOUQINGYI_HID, quality: 2 }, (qualityUpRes) => {
                      checkSuccessResponse(qualityUpRes);
                      setTimeout(() => {
                        expect(msgReceiveCnt).to.be.equal(2);
                        done();
                      }, 1000);
                    });
                  } else {
                    checkSuccessResponse(starUpRes);
                  }
                });
              }
            }, 200 * (i - 2) * ABI_STAGE.END + 200 * j); // 50ms 为间隔，避免并发导致的连续升星失败
          }
        }
      });
    });
  });

  it('测试世界频道消息', function (done) {
    testGroupMsg(pinusClient, roleInfo, pinusClientT, CHANNEL_PREFIX.WORLD, roleInfo.serverId, done);
  });

  it('测试加入相同军团', function (done) {
    console.log("1: ", roleInfo.roleId, roleInfo.guildCode)
    console.log("2: ", roleInfoT.roleId, roleInfoT.guildCode)
    if (roleInfo.guildCode !== roleInfoT.guildCode) {
      pinusClientT.request('guild.guildHandler.debugJoinGuild', { code: roleInfo.guildCode, magicWord: DEBUG_MAGIC_WORD }, (res) => {
        console.log(roleInfo.guildCode)
        checkSuccessResponse(res, false);
        done();
      });
    } else {
      done();
    }
  });

  it('测试军团频道消息', function (done) {
    console.log(roleInfo.guildCode)
    console.log(roleInfoT.guildCode)
    testGroupMsg(pinusClient, roleInfo, pinusClientT, CHANNEL_PREFIX.GUILD, roleInfo.guildCode, done);
  });

  it('测试军团通知修改推送', function (done) {
    const newNotice = new Date().toLocaleDateString();
    let msgReceiveCnt = 0;
    function checkNoticeRes(res) {
      checkSuccessResponse(res);
      expect(res.data.content).to.be.equal(newNotice);
      msgReceiveCnt += 1;
    }
    pinusClientT.on(PUSH_ROUTE.GROUP_MSG, (res) => {
      checkNoticeRes(res);
    });
    pinusClient.on(PUSH_ROUTE.GROUP_MSG, (res) => {
      checkNoticeRes(res);
    });
    pinusClient.request('guild.guildHandler.getMyGuildInfo', {}, (res) => {
      checkSuccessResponse(res);
      expect(res.data).to.have.deep.property('hasGuild').that.is.an('boolean');
      if (res.data.hasGuild) {
        expect(res.data).to.have.deep.property('code').that.is.an('string');
        expect(res.data).to.have.deep.property('name').that.is.an('string');
        expect(res.data).to.have.deep.property('notice').that.is.an('string');
        expect(res.data).to.have.deep.property('introduce').that.is.an('string');
        expect(res.data).to.have.deep.property('ceLimit').that.is.an('number');
        expect(res.data).to.have.deep.property('isAuto').that.is.an('boolean');
        const { code, name, notice, introduce, ceLimit, isAuto } = res.data;
        pinusClient.request('guild.guildHandler.setGuildInfo', { code, name: `${name}1`, notice: newNotice, introduce, ceLimit, isAuto }, (setRes) => {
          checkSuccessResponse(setRes);
          expect(setRes.data.notice).to.be.equal(newNotice);
          setTimeout(() => {
            expect(msgReceiveCnt).to.be.equal(2);
            pinusClientT.off(PUSH_ROUTE.GROUP_MSG);
            pinusClient.off(PUSH_ROUTE.GROUP_MSG);
            done();
          }, 500);
        });
      }
    });
  });

  it('更新私聊阅读时间', function (done) {
    pinusClient.request('chat.chatHandler.sendPrivateMessage', sendPrivateMessageParm(roleInfoT, TEXT_MSG), (res) => {
      console.log('###', roleInfo.roleId)
      checkSuccessResponse(res);
      expect(res.data.content).to.equal(TEXT_MSG.content);
    });
    setTimeout(() => {
      console.log('###', roleInfo.roleId)
      pinusClientT.request('chat.chatHandler.readPrivateMessage', { targetRoleId: roleInfo.roleId }, (res) => {
        checkSuccessResponse(res);
        expect(res.data).to.be.an('object');
        expect(res.data.targetRoleId).to.be.equal(roleInfo.roleId);
        expect(Date.parse(res.data.lastReadTime)).to.be.above(Date.parse(res.data.lastChatTime));
        expect(res.data.unreadCnt).to.be.equal(0);
        done();
      });
    }, 1000);
  });

  it('举报消息', function (done) {
    pinusClient.request('chat.chatHandler.accuse', { targetRoleId: roleInfoT.roleId, targetMsgCode: 'test', reason: 1 }, (res) => {
      checkSuccessResponse(res);
      expect(res.data).to.be.an('object');
      expect(res.data.roleId).to.be.equal(roleInfo.roleId);
      expect(res.data.targetRoleId).to.be.equal(roleInfoT.roleId);
      expect(res.data.targetMsgCode).to.be.equal('test');
      done();
    });
  });
});
