import { Client } from './Client';
import 'mocha';
import { PinusWSClient } from 'pinus-robot-plugin';
import { expect } from 'chai';
import { addItemsIfNotEnough, checkSuccessResponse } from './CheckPatten';
import { DEBUG_MAGIC_WORD, AUCTION_SOURCE, CURRENCY_BY_TYPE, CURRENCY_TYPE, AUCTION_STAGE, DIVIDEND_STATUS, LOT_STATUS } from '../app/consts';

const GOOD_ID_TIEJIAN = 1;
const GOOD_ID_GANGJIAN = 2;

function checkLot(lot) {
    expect(lot.auctionStage).to.be.a('number');
    expect(lot.sourceType).to.be.a('number');
    expect(lot.sourceCode).to.be.a('string');
    expect(lot.serverId).to.be.a('number');
    expect(lot.guildCode).to.be.a('string');
    expect(lot.code).to.be.a('string');
    expect(lot.gid).to.be.a('number');
    expect(lot.count).to.be.a('number');
    expect(lot.maxPrice).to.be.a('number');
    expect(lot.curPrice).to.be.a('number');
    expect(lot.bidRoles).to.be.a('array');
    expect(Date.parse(lot.begin)).to.be.a('number');
    expect(Date.parse(lot.end)).to.be.a('number');
}

function checkLots(lots) {
    for (let lot of lots) {
        checkLot(lot);
    }
}

function checkDividend(dividend) {
    expect(dividend.sourceType).to.be.a('number');
    expect(dividend.sourceCode).to.be.a('string');
    expect(dividend.serverId).to.be.a('number');
    expect(dividend.guildCode).to.be.a('string');
    expect(dividend.code).to.be.a('string');
    expect(dividend.status).to.be.a('number');
    expect(dividend.totalPrice).to.be.a('number');
    expect(dividend.dividends).to.be.an('array');
    expect(Date.parse(dividend.begin)).to.be.a('number');
}

function checkDividends(dividends) {
    for (let dividend of dividends) {
        checkDividend(dividend);
    }
}

describe('拍卖行测试', function () {
    let pinusClient: PinusWSClient;
    let roleInfo;

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

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

    it('添加拍品', function (done) {
        const sourceCode = Math.random().toString(36).slice(-8);
        pinusClient.request('guild.auctionHandler.debugAddLots', { magicWord: DEBUG_MAGIC_WORD, sourceType: AUCTION_SOURCE.GATE, sourceCode, poolId: 1 }, (res) => {
            checkSuccessResponse(res);
            expect(res.data.lots).to.be.an('array');
            for (let lot of res.data.lots) {
                checkLot(lot);
            }
            done();
        });
    });

    it('获取拍卖行数据', function (done) {
        try {
            pinusClient.request('guild.auctionHandler.getAuction', {}, (res) => {
                checkSuccessResponse(res);

                expect(res.data.lots).to.be.an('array');
                checkLots(res.data.lots);
                expect(res.data.dividends).to.be.an('array');
                checkDividends(res.data.dividends);
                done();
            });
        } catch (e) {
            console.log('offer got err:', e);
            done();
        }
    });

    it('出价，竞价和一口价', function (done) {
        let gid = null;
        pinusClient.on('onJewelAdd', (res) => {
            checkSuccessResponse(res);
            expect(res.data.equipInfos).to.be.an('array');
            for (let info of res.data.equipInfos) {
                expect(info.id).to.be.equal(gid);
            }
        });
        addItemsIfNotEnough(roleInfo, pinusClient, 31002, 100000, () => {
            pinusClient.request('guild.auctionHandler.getAuction', {}, (res) => {
                checkSuccessResponse(res);
                expect(res.data.lots).to.be.an('array');
                checkLots(res.data.lots);
                expect(res.data.dividends).to.be.an('array');
                checkDividends(res.data.dividends);
                if (res.data.lots.length === 0) {
                    console.warn('没有拍品');
                    done();
                    return;
                }
                const curTime = new Date();
                let unsoldLots = res.data.lots.filter(lot => { return lot.status !== LOT_STATUS.SOLD && lot.curBuyer !== roleInfo.roleId && lot.end <= curTime });
                if (unsoldLots.length === 0) {
                    console.warn('没有可出价的拍品');
                    done();
                    return;
                }
                pinusClient.request('guild.auctionHandler.offer', { code: unsoldLots[0].code, auctionStage: AUCTION_STAGE.GUILD, max: false, magicWord: DEBUG_MAGIC_WORD }, (res) => {
                    checkSuccessResponse(res);
                    checkLot(res.data.lot);
                    if (res.data.dividend) {
                        checkDividend(res.data.dividend);
                    }
                    expect(res.data.lot.curBuyer).to.be.equal(roleInfo.roleId);
    
                    unsoldLots.shift();
                    if (unsoldLots.length === 0) {
                        console.warn('没有测试一口价的情况');
                        done();
                        return;
                    }
                    gid = unsoldLots[0].gid;
                    pinusClient.request('guild.auctionHandler.offer', { code: unsoldLots[0].code, auctionStage: AUCTION_STAGE.GUILD, max: true, magicWord: DEBUG_MAGIC_WORD }, (res) => {
                        checkSuccessResponse(res);
                        checkLot(res.data.lot);
                        if(res.data.dividend) {
                            checkDividend(res.data.dividend);
                        }
                        expect(res.data.lot.curBuyer).to.be.equal(roleInfo.roleId);
                        setTimeout(() => {
                            done();
                        }, 1000);
                    });
                });
            });
        });
    });

    it('关注后取关', function (done) {
        pinusClient.request('guild.auctionHandler.getAuction', {}, (res) => {
            checkSuccessResponse(res);
            expect(res.data.lots).to.be.an('array');
            checkLots(res.data.lots);
            expect(res.data.dividends).to.be.an('array');
            checkDividends(res.data.dividends);
            if (res.data.lots.length === 0) {
                console.warn('没有可关注的拍品');
                done();
                return;
            }
            const code = res.data.lots[0].code;
            pinusClient.request('guild.auctionHandler.watchLot', { code }, (res) => {
                checkSuccessResponse(res);
                checkLot(res.data.lot);
                expect(res.data.lot.watchingRoles.indexOf(roleInfo.roleId)).to.be.above(-1);
                pinusClient.request('guild.auctionHandler.unWatchLot', { code }, (res) => {
                    checkSuccessResponse(res);
                    checkLot(res.data.lot);
                    expect(res.data.lot.watchingRoles.indexOf(roleInfo.roleId)).to.be.equal(-1);
                    done();
                });
            });
        });
    });

    it('查看分红', function (done) {
        pinusClient.request('guild.auctionHandler.checkDividend', {}, (res) => {
            checkSuccessResponse(res);
            checkDividends(res.data.dividends);
            done();
        });
    });

    it('领取分红', function (done) {
        pinusClient.on('onItemUpdate', (res) => {
            checkSuccessResponse(res);
            expect(res.data.goods).to.be.an('array');
            for (let info of res.data.goods) {
                expect(info.id).to.be.equal(CURRENCY_BY_TYPE.get(CURRENCY_TYPE.GOLD));
            }
        });
        pinusClient.request('guild.auctionHandler.debugSetDividendStatusV2', { magicWord: DEBUG_MAGIC_WORD, sourceType: AUCTION_SOURCE.GATE, status: DIVIDEND_STATUS.END }, (res) => {
            checkSuccessResponse(res);
            checkDividend(res.data.dividend);
            // TODO: 找个测试领取分红的方法
            const dividend = res.data.dividend.dividends.find(d => { return d.roleId === roleInfo.roleId });
            if (!dividend) {
                console.warn('未测试到领取分红的情况');
                done();
                return;
            }
            pinusClient.request('guild.auctionHandler.getDividend', { code: res.data.dividend.code }, (res) => {
                checkSuccessResponse(res);
                expect(res.data.dividend).to.be.an('object');
                expect(res.data.dividend.roleId).to.be.a('string');
                expect(res.data.dividend.posNum).to.be.a('number');
                expect(res.data.dividend.weekendNum).to.be.a('number');
                expect(res.data.dividend.total).to.be.a('number');
                expect(res.data.dividend.status).to.be.a('number');
                setTimeout(() => {
                    done();
                }, 100);
            });
        });
    });

    it('查看我的关注', function (done) {
        pinusClient.request('guild.auctionHandler.getAuction', {}, (res) => {
            checkSuccessResponse(res);
            expect(res.data.lots).to.be.an('array');
            checkLots(res.data.lots);
            expect(res.data.dividends).to.be.an('array');
            checkDividends(res.data.dividends);
            if (res.data.lots.length === 0) {
                console.warn('没有可关注的拍品');
                done();
                return;
            }
            const code = res.data.lots[0].code;
            pinusClient.request('guild.auctionHandler.watchLot', { code }, (res) => {
                checkSuccessResponse(res);
                checkLot(res.data.lot);
                expect(res.data.lot.watchingRoles.indexOf(roleInfo.roleId)).to.be.above(-1);
                pinusClient.request('guild.auctionHandler.myWatching', {}, (res) => {
                    checkSuccessResponse(res);
                    checkLots(res.data.lots);
                    done();
                });
            });
        });
    });

    it('更新拍品阶段的测试接口', function (done) {
        pinusClient.request('guild.auctionHandler.getAuction', {}, (res) => {
            checkSuccessResponse(res);
            expect(res.data.lots).to.be.an('array');
            checkLots(res.data.lots);
            expect(res.data.dividends).to.be.an('array');
            checkDividends(res.data.dividends);
            if (res.data.lots.length === 0) {
                console.warn('没有可更新阶段的拍品');
                done();
                return;
            }
            const code = res.data.lots[0].code;
            pinusClient.request('guild.auctionHandler.debugSetLotStage', { code, magicWord: DEBUG_MAGIC_WORD, auctionStage: AUCTION_STAGE.GUILD }, (res) => {
                checkSuccessResponse(res);
                checkLot(res.data.lot);
                done();
            });
        });
    });

    it('查看我的拍卖纪录', function (done) {
        pinusClient.request('guild.auctionHandler.offerRecs', { count: 10 }, (res) => {
            checkSuccessResponse(res);
            expect(res.data.bidRecs).to.be.an('array');
            if (res.data.bidRecs.length === 0) {
                console.warn('没有我的拍卖纪录');
                done();
                return;
            }
            for (let bidRec of res.data.bidRecs) {
                expect(bidRec.roleId).to.be.a('string');
                expect(bidRec.price).to.be.a('number');
                expect(Date.parse(bidRec.time)).to.be.a('number');
                expect(bidRec.status).to.be.a('number');
                expect(bidRec.gid).to.be.a('number');
            }
            done();
        });
    });


    it('获取军团拍卖记录', function (done) {
        pinusClient.request('guild.auctionHandler.guildLotRecs', { count: 10 }, (res) => {
            checkSuccessResponse(res);
            expect(res.data.lotRecs).to.be.an('array');
            if (res.data.lotRecs.length === 0) {
                console.warn('没有军团拍卖纪录');
                done();
                return;
            }
            for (let lotRec of res.data.lotRecs) {
                expect(lotRec.price).to.be.a('number');
                expect(lotRec.count).to.be.a('number');
                expect(Date.parse(lotRec.time)).to.be.a('number');
                expect(lotRec.gid).to.be.a('number');
                expect(lotRec.sourceType).to.be.a('number');
                expect(lotRec.max).to.be.a('boolean');
                expect(lotRec.sold).to.be.a('boolean');
            }
            done();
        });
    });

    it('测试接口，军团拍卖定时', function (done) {
        pinusClient.request('guild.auctionHandler.debugScheduleStartGuild', { magicWord: DEBUG_MAGIC_WORD }, (res) => {
            checkSuccessResponse(res, false);
            done();
        });
    });

    it('测试接口，世界拍卖定时', function (done) {
        pinusClient.request('guild.auctionHandler.debugScheduleStartWorld', { magicWord: DEBUG_MAGIC_WORD }, (res) => {
            checkSuccessResponse(res, false);
            done();
        });
    });

    it('测试接口，拍卖结束定时', function (done) {
        pinusClient.request('guild.auctionHandler.debugScheduleStopAuction', { magicWord: DEBUG_MAGIC_WORD }, (res) => {
            checkSuccessResponse(res, false);
            done();
        });
    });

    it('测试接口，结算分红定时', function (done) {
        pinusClient.request('guild.auctionHandler.debugScheduleSendUngotDividend', { magicWord: DEBUG_MAGIC_WORD }, (res) => {
            checkSuccessResponse(res, false);
            done();
        });
    });
});
