import { DEBUG_MAGIC_WORD } from '../../shared/consts';
import { GVGTeamType } from './../../shared/db/GVGTeam';
import { GVGUserDataType } from './../../shared/db/GVGUserData';
import { LineupHero } from './../../shared/domain/roleField/hero';
import { Client } from './Client';
import 'mocha';
import { PinusWSClient } from 'pinus-robot-plugin';
import { expect } from 'chai';
import { checkSuccessResponse } from './CheckPatten';
import { GVGHeroInfo } from '../../shared/domain/dbGeneral';

describe('gvg激战期测试', function () {
    let pinusClient: PinusWSClient;
    let roleInfo;

    before(function (done) {
      const c = new Client();
      const timer = setInterval(() => {
        if (c.client && c.roleInfo) {
          pinusClient = c.client;
          roleInfo = c.roleInfo;
          clearInterval(timer);
          done();
        }
      }, 500);
    });

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

    // 测试保存队伍
    it.skip('测试保存队伍', function (done) {
        const lineup : LineupHero[] = [
            {
                actorId: 1, // 武将
                dataId: 2,  // 出兵表上的位置
                order: 3,   // 行动
            }
        ];

        pinusClient.request('guild.gvgBattleHandler.saveTeam', {
            index: 1,
            head: 1,
            frame: 1,
            spine: 1,
            lineup,
        }, (data) => {
            checkSuccessResponse(data);
            // 检查返回值中的 teams
            expect(data.data.teams).to.be.an('array');
            done();
        });
    });

    // 测试获取城池信息
    it.skip('测试获取城池信息', function (done) {
        const cityId = 1;
        // 通过测试接口尝试创建城市
        // pinusClient.request('guild.gvgBattleHandler.createCity', {
        //     cityId, magicWord: DEBUG_MAGIC_WORD
        // }, (data) => {
        //     checkSuccessResponse(data);
        //     checkCity(data.data.city);
            pinusClient.request('guild.gvgBattleHandler.getCity', {
                cityId,
            }, (data) => {
                checkSuccessResponse(data);
                // 检查返回值中的 city
                expect(data.data.cityId).to.be.a('number');
                expect(data.data.guardLeague).to.be.an('object');
                expect(data.data.guardLeague.leagueCode).to.be.a('string');
                expect(data.data.guardLeague.name).to.be.a('string');
                expect(data.data.guardLeague.icon).to.be.a('number');
                expect(data.data.guardStartTime).to.be.a('number');
                expect(data.data.startTime).to.be.a('number');
                expect(data.data.endTime).to.be.a('number');
                expect(data.data.ourTeamCnt).to.be.a('number');
                expect(data.data.oppTeamCnt).to.be.a('number');
                done();
            });
        // });
    });

    // 进入城池
    it.skip('进入城池', function (done) {
        const cityId = 1;
        pinusClient.request('guild.gvgBattleHandler.enterCity', {
            cityId,
        }, (data) => {
            checkSuccessResponse(data);
            // 检查 city 中的属性类型是否合法
            expect(data.data.cityId).to.be.a('number');
            expect(data.data.ranks).to.be.an('array');
            expect(data.data.recs).to.be.an('array');
            expect(data.data.teams).to.be.an('array');
            data.data.teams.forEach((team) => {
                checkTeam(team);
            });
            done();
        });
    });

    // 离开城池
    it.skip('离开城池', function (done) {
        pinusClient.request('guild.gvgBattleHandler.leaveCity', {}, (data) => {
            checkSuccessResponse(data);
            done();
        });
    });

    // 开始移动
    it.skip('开始移动', function (done) {
        const cityId = 1;
        const areaId = 1;
        const teamCode = '';
        pinusClient.request('guild.gvgBattleHandler.startMove', {
            cityId,
            areaId,
            teamCode,
        }, (data) => {
            checkSuccessResponse(data);
            setTimeout(() => {
                // 停止移动
                it.skip('停止移动', function (done) {
                    pinusClient.request('guild.gvgBattleHandler.stopMove', {}, (data) => {
                        checkSuccessResponse(data);
                        expect(data.data.areaId).to.be.a('number');
                        expect(data.data.cityId).to.be.a('number');
                        checkTeam(data.data.curTeam);
                        // players
                        expect(data.data.players).to.be.an('array');
                        data.data.players.forEach((player) => {
                            checkPlayer(player);
                        });
                        done();
                    });
                });
            }, 2000);
        });
    });

    // 队伍入驻积分点
    it.skip('队伍入驻积分点', function (done) {
        const cityId = 1;
        const areaId = 1;
        const pointId = 1;
        const teamCode = '';
        pinusClient.request('guild.gvgBattleHandler.teamSettle', {
            cityId,
            areaId,
            teamCode,
            pointId,
        }, (data) => {
            checkSuccessResponse(data);
            checkTeam(data.data.curTeam);
            done();
        });
    });

    // 队伍离开积分点
    it.skip('队伍离开积分点', function (done) {
        pinusClient.request('guild.gvgBattleHandler.teamLeave', {}, (data) => {
            checkSuccessResponse(data);
            done();
        });
    });


    function battle(teamCode: string, oppoTeamCode: string, isSuccess: boolean, done) {
        pinusClient.request('guild.gvgBattleHandler.battleStart', {
            teamCode,
            oppoTeamCode,
        }, (data) => {
            checkSuccessResponse(data);
            const { battleCode } = data.data;
            expect(battleCode).to.be.a('string');
            setTimeout(() => {
                // 队伍结束攻击 battleEnd
                it.skip('队伍结束攻击', function (done) {
                    pinusClient.request('guild.gvgBattleHandler.battleEnd', {
                        battleCode,
                        isSuccess,
                    }, (data) => {
                        checkSuccessResponse(data);
                        if (isSuccess) {
                            checkLeagueGoods(data.data.leagueGoods);
                        }
                        done();
                    });
                });
            }, 5000);
        });
    }

    // 队伍开始攻击且获胜
    it.skip('队伍开始攻击且获胜', function (done) {
        const teamCode = '';
        const oppoTeamCode = '';
        battle(teamCode, oppoTeamCode, true, done);
    });

    // 队伍开始攻击且失败
    it.skip('队伍开始攻击且失败', function (done) {
        const teamCode = '';
        const oppoTeamCode = '';
        battle(teamCode, oppoTeamCode, false, done);
    });

    function useItem(itemId: number, teamCode: string, done) {
        pinusClient.request('guild.gvgBattleHandler.useItem', {
            itemId,
            teamCode,
        }, (data) => {
            checkSuccessResponse(data);
            checkTeam(data.data.team);
            done();
        });
    }

    // 使用道具
    // ! 不同道具添加多个测试用例
    it.skip('使用道具', function (done) {
        const itemId = 1;
        const teamCode = '';
        useItem(itemId, teamCode, done);
    });

    // 复活队伍
    it.skip('复活队伍', function (done) {
        const teamCode = '';
        pinusClient.request('guild.gvgBattleHandler.reviveTeam', {}, (data) => {
            checkSuccessResponse(data);
            checkTeam(data.data.team);
            done();
        });
    });

    // 获取战报 getRecs
    // ! 战报具体内容未检查
    it.skip('获取战报', function (done) {
        const type = 1;
        pinusClient.request('guild.gvgBattleHandler.getRecs', {
            type,
        }, (data) => {
            checkSuccessResponse(data);
            expect(data.data.recs).to.be.an('array');
            done();
        });
    });

    // 获取概况
    it.skip('获取概况', function (done) {
        pinusClient.request('guild.gvgBattleHandler.getOverview', {}, (data) => {
            checkSuccessResponse(data);
            expect(data.data.cities).to.be.an('array');
            data.data.cities.forEach((city) => {
                checkCity(city);
            });
            done();
        });
    });

    // 获取区域上的队伍 getAreaTeams
    it.skip('获取区域上的队伍', function (done) {
        const cityId = 1;
        const areaIds = [1, 2, 3];
        pinusClient.request('guild.gvgBattleHandler.getAreaTeams', {
            cityId,
            areaIds,
        }, (data) => {
            checkSuccessResponse(data);
            expect(data.data.teams).to.be.an('array');
            data.data.teams.forEach((team) => {
                checkTeam(team);
            });
            done();
        });
    });
})

// 检查城市数据是否合法
export function checkCity(city) {
    expect(city).to.be.an('object');
    expect(city.cityId).to.be.a('number');
    expect(city.configId).to.be.a('number');
    expect(city.userCnt).to.be.a('number');
    expect(city.teamCnt).to.be.a('number');
    if (city.guardLeague) {
        expect(city.guardLeague).to.be.a('string');
        expect(city.guardLeagueName).to.be.a('string');
    }
}

// 检查队伍数据是否合法
export function checkTeam(team: GVGTeamType) {
    expect(team).to.be.an('object');
    expect(team.teamCode).to.be.a('string');
    expect(team.leagueCode).to.be.a('string');
    expect(team.areaId).to.be.a('number');
    expect(team.cityId).to.be.a('number');
    expect(team.head).to.be.a('number');
    expect(team.frame).to.be.a('number');
    expect(team.spine).to.be.a('number');
    expect(team.durability).to.be.a('number');
    expect(team.restartTime).to.be.a('number');
    expect(team.attackTime).to.be.a('number');
    expect(team.startMoveTime).to.be.a('number');
    expect(team.stopMoveTime).to.be.a('number');
    expect(team.defenseTime).to.be.a('number');
    checkLineup(team.lineup);
}

// 检查阵容数据是否合法
export function checkLineup(lineup: GVGHeroInfo[]) {
    expect(lineup).to.be.an('array');
    // 循环检查阵容数据是否合法
    lineup.forEach((hero) => {
        expect(hero.actorId).to.be.a('number');
        expect(hero.dataId).to.be.a('number');
    });
}

// 检查玩家数据是否合法
// ! 不完整
export function checkPlayer(user: GVGUserDataType) {
    expect(user).to.be.an('object');
    expect(user.roleId).to.be.a('string');
    expect(user.leagueCode).to.be.a('string');
    expect(user.configId).to.be.a('string');
    expect(user.active).to.be.a('number');
    expect(user.receivedLv).to.be.a('number');
    expect(user.receiveCurrencyTime).to.be.a('number');
}

// check leagueGoods
export function checkLeagueGoods(leagueGoods) {
    expect(leagueGoods).to.be.an('array');
    leagueGoods.forEach((good) => {
        expect(good).to.be.an('object');
        expect(good.itemType).to.be.a('number');
        expect(good.id).to.be.a('number');
        expect(good.count).to.be.a('number');
    });
}
