import { UserModel } from '@db/User';
import { RoleModel } from '@db/Role';
import { HeroModel } from '@db/Hero';

import { Service } from 'egg';
import { STATUS, REDIS_KEY, WAR_TYPE } from '@consts';
import { ItemModel } from '@db/Item';
import { gameData } from '@pubUtils/data';
import { smsModel } from '@db/Sms';
import { isString } from 'underscore';
import { GiftCodeModel } from '@db/GiftCode';
import GiftCodeDetail, { GiftCodeDetailModel } from '@db/GiftCodeDetail';
import { deletRole } from '@pubUtils/roleUtil';
import { RScriptRecordModel } from '@db/RScriptRecord';
import { DicWar } from '@pubUtils/dictionary/DicWar';
import { SearchHeroParam, SearchUserParam, SearchGiftCodeParam, SearchGiftCodeDetailParam, SearchItemParam, SearchGuildParam, SearchRoleParam } from '@domain/backEndField/search';
import { CreateGiftCode, UpdateGiftCode } from '@domain/backEndField/params';
import { isNumber } from 'util';
import { GuildModel } from '@db/Guild';
import { RedisClient } from 'redis';
import { UserGuildModel } from '@db/UserGuild';
import { TowerRecordModel } from '@db/TowerRecord';
import { nowSeconds } from '@pubUtils/timeUtil';
import { RoleCeModel, RoleCeType } from '@db/RoleCe';
import { HangUpRecordModel } from '@db/HangUpRecord';
import { UserOrderModel } from '@db/UserOrder';
const Excel = require('exceljs');

// import { resResult } from '@pubUtils/util';

// import * as fs from 'fs';

/**
 * Test Service
 */
export default class GMUsers extends Service {

    /**
     * 根据类型等搜索玩家
     */
    public async getuserlist(page: number, pageSize: number, sortField: string, sortOrder: string, form: SearchUserParam) {
        const { ctx } = this;

        const users = await UserModel.findByCondition(page, pageSize, sortField, sortOrder, form);
        const total = await UserModel.countByCondition( form )

        let list = [];
        for (let user of users) {
            let role = await RoleModel.findAllByUid(user.uid);
            let sms = await smsModel.findByTel(user.tel);

            list.push({ ...user, role, isFixed: sms ? sms.isFixed : false, code: sms ? sms.code : "", env: ctx.app.config.realEnv });
        }

        return ctx.service.utils.resResult(STATUS.SUCCESS, { list, total })

    }

    // public async createRole(uid: number, serverId: number, roleName: string) {
    //     console.log('enter Auth createRole');
    //     const ctx = this.ctx;

    //     const roleId = ctx.service.utils.genCode(10);
    //     const code = ctx.service.utils.genCode(6);
    //     const seqId = await Counter.getNewCounter(COUNTER.ROLE) || -1;
    //     const role = await RoleModel.createRole(uid, serverId, { roleId, code, roleName, seqId });
    //     if (role) {
    //         return ctx.service.utils.resResult(STATUS.SUCCESS);
    //     } else {
    //         console.error('create role error');
    //         return ctx.service.utils.resResult(STATUS.INTERNAL_ERR);
    //     }
    // }

    // public async addAuth(uid: number, auth: number) {
    //     console.log('enter Auth addAuth');
    //     const ctx = this.ctx;

    //     const user = await UserModel.addAuth(uid, auth);
    //     if (user) {
    //         return ctx.service.utils.resResult(STATUS.SUCCESS);
    //     } else {
    //         console.error('add auth error');
    //         return ctx.service.utils.resResult(STATUS.INTERNAL_ERR);
    //     }
    // }

    public checkTelNo(telNo: string) {
        if (!isString(telNo)) {
            return { status: 1, data: '参数类型错误' };
        }
        if (telNo.length !== 11) {
            return { status: 1, data: '手机号长度错误' };
        }
        return { status: 0, data: '手机号合法' };
    }

    public async fixSms(tel: string) {
        console.log('enter Auth fix sms');
        const ctx = this.ctx;
        const checkTel = this.checkTelNo(tel);
        if (checkTel.status == 1) {
            return ctx.service.utils.resResult(STATUS.INTERNAL_ERR, checkTel.data);
        }
        const sms = await smsModel.fixSms(tel);
        if (sms) {
            return ctx.service.utils.resResult(STATUS.SUCCESS);
        } else {
            console.error('fix sms error');
            return ctx.service.utils.resResult(STATUS.INTERNAL_ERR);
        }
    }

    public async deleteRole(roleId: string) {
        console.log('enter Auth deleteRole');
        const ctx = this.ctx;
        let result = await deletRole(roleId);
        if(!result) return ctx.service.utils.resResult(STATUS.WRONG_PARMS);
        return ctx.service.utils.resResult(STATUS.SUCCESS);
    }

    /**
     * 根据类型等搜索玩家
     */
    public async getrolelist(page: number, pageSize: number, sortField: string, sortOrder: string, form: SearchRoleParam) {
        const { ctx } = this;

        if(!!form.channelId) {
            let user = await UserModel.findUserByChannelRegex(form.channelId);
            if(!user) {
                return ctx.service.utils.resResult(STATUS.SUCCESS, { list: [], total: 0 });
            }
            form.uid = user.uid;
        }

        const roles = await RoleModel.findByCondition(page, pageSize, sortField, sortOrder, form);
        const total = await RoleModel.countByCondition( form )

        let list = [];
        for (let role of roles) {
            let heroCount = await HeroModel.count({ roleId: role.roleId }).lean();
            let itemCount = await ItemModel.count({ roleId: role.roleId }).lean();

            let { roleId, roleName, serverId, lv, gold, coin, ce, blockType = 0, blockReason = '', fixedIpLocation, ip, ipLocation, totalPay } = role;
            let { uid, tel } = role.userInfo;
            let user = await UserModel.findUserByUid(role.userInfo.uid);

            list.push({
                key: roleId, roleId, roleName, serverId, lv, uid, tel, heroCount, itemCount, gold, coin, ce, blockType, blockReason, fixedIpLocation, ip, ipLocation, channelId: user?.channelId, totalPay, channelType: user?.channelType,
                env: ctx.app.config.realEnv
            });
        }

        return ctx.service.utils.resResult(STATUS.SUCCESS, { list, total })
    }

    public async getpaystatic(page: number, pageSize: number, form: { beginTime: number, endTime: number, serverId: number }) {
        const { ctx } = this;
        let match = { state: 1 };
        if(form.beginTime && form.endTime) {
            match['beginTime'] = { $gt: new Date(form.beginTime) };
            match['endTime'] = { $lt: new Date(form.endTime) };
        }
        if(form.serverId) {
            match['serverId'] = form.serverId;
        }
        console.log(match)
        let list = await UserOrderModel.aggregate([
            { $match: match },
            { $group: { '_id': '$roleId', sum: { '$sum': '$price' }, count: { '$sum': 1 }, max: { $max:'$price'}, lastTime: { $max: '$updatedAt' }  } },
            { $lookup: { from: 'roles', localField: '_id', foreignField: 'roleId', as: 'role' } },
            { $unwind: '$role' },
            { $project: { _id: 0, roleId: '$_id', roleName: '$role.roleName', guildName: '$role.guildName', serverId: '$role.serverId', lv: '$role.lv', sum: 1, count: 1, max: 1, lastTime: {$dateToString: {format: '%Y-%m-%d %H:%M:%S', date:{$add:['$lastTime',28800000]}}}, env: ctx.app.config.realEnv } },
            { $sort: { 'sum': -1 } },
            { $limit: pageSize },
            { $skip: (page - 1) * pageSize },
        ])
        return ctx.service.utils.resResult(STATUS.SUCCESS, { list })
    }

    // public async createHero(uids: Array<string>, _hid: string, _hlv: string) {
    //     const { ctx } = this;
    //     console.log('gm createHero', uids, _hid, _hlv);
    //     let hlv = parseInt(_hlv);
    //     if (isNaN(hlv)) return ctx.service.utils.resResult(STATUS.WRONG_PARMS);
    //     let hids = (_hid as string).split('&').map(cur => parseInt(cur));
    //     for (let hid of hids) {
    //         if (isNaN(hid)) return ctx.service.utils.resResult(STATUS.WRONG_PARMS);
    //     }

    //     for (let roleId of uids) {
    //         let role = await RoleModel.findByRoleId(roleId);
    //         if (role) {
    //             let heroInfos = new Map();
    //             for (let hid of hids) {
    //                 let heroInfo = ctx.service.utils.getInitHeroById(hid);
    //                 heroInfos.set(hid, {...heroInfo});
    //             }

    //             let createHero = new CreateHeroes(roleId, role.roleName, role.serverId);
    //             await createHero.createWithHeroInfo(heroInfos);

    //         } else {
    //             return ctx.service.utils.resResult(STATUS.GM_CREATE_ERROR, null, '未找到角色' + roleId)
    //         }
    //     }

    //     return ctx.service.utils.resResult(STATUS.SUCCESS, { uids });
    // }


    // public async createItem(uids: Array<string>, _itemid: string, _itemcount: string) {
    //     const { ctx } = this;
    //     console.log('gm createItem', uids, _itemid, _itemcount);
    //     let itemids = (_itemid as string).split('&').map(cur => parseInt(cur));
    //     for (let itemid of itemids) {
    //         if (isNaN(itemid)) return ctx.service.utils.resResult(STATUS.WRONG_PARMS);
    //     }
    //     let itemcount = parseInt(_itemcount);
    //     if (isNaN(itemcount)) return ctx.service.utils.resResult(STATUS.WRONG_PARMS);

    //     let flag = 0, msg = '创建失败';
    //     let datas: {id: number, count: number }[] = []
    //     for (let itemid of itemids) {
    //         let dicGoods = gameData.goods.get(itemid);
    //         let itidObj = ITID.get(dicGoods.itid);

    //         if (!dicGoods) {
    //             flag = 1, msg = "未找到道具" + itemid;
    //         } else if (!itidObj) {
    //             flag = 1, msg = "未找到道具" + itemid;
    //         } else {
    //             datas.push({ id: itemid, count: itemcount });
    //         }
    //     }
    //     if(flag == 0) {
    //         for (let roleId of uids) {
    //             let role = await RoleModel.findByRoleId(roleId);
    //             if (role) {
    //                 await addBags(roleId, role.roleName, datas, ITEM_CHANGE_REASON.DEBUG);
    //             } else {
    //                 flag = 1, msg = '未找到角色' + roleId;
    //             }
    //         }
    //     }

    //     if (flag) {
    //         return ctx.service.utils.resResult(STATUS.GM_CREATE_ERROR, null, msg);
    //     } else {
    //         return ctx.service.utils.resResult(STATUS.SUCCESS, { uids });
    //     }
    // }

    // public async addGold(uids: Array<string>, _count: string) {
    //     const { ctx } = this;
    //     console.log('gm addGold', uids, _count);
    //     let count = parseInt(_count);
    //     if (isNaN(count)) return ctx.service.utils.resResult(STATUS.WRONG_PARMS);
    //     for (let roleId of uids) {
    //         await RoleModel.addGoldFree(roleId, count);
    //     }

    //     return ctx.service.utils.resResult(STATUS.SUCCESS, { uids });
    // }

    // public async addCoin(uids: Array<string>, _count: string) {
    //     const { ctx } = this;
    //     console.log('gm addCoin', uids, _count);
    //     let count = parseInt(_count);
    //     if (isNaN(count)) return ctx.service.utils.resResult(STATUS.WRONG_PARMS);
    //     for (let roleId of uids) {
    //         await RoleModel.addCoin(roleId, count);
    //     }

    //     return ctx.service.utils.resResult(STATUS.SUCCESS, { uids });
    // }
    // public async addSkin(uids: Array<string>, _id: string) {
    //     const { ctx } = this;
    //     console.log('gm addSkin', uids, _id);
    //     let id = parseInt(_id);
    //     if (isNaN(id)) return ctx.service.utils.resResult(STATUS.WRONG_PARMS);
    //     for (let roleId of uids) {
    //         let role = await RoleModel.findByRoleId(roleId);
    //         await addSkin(roleId, role.roleName, id, false);
    //     }

    //     return ctx.service.utils.resResult(STATUS.SUCCESS, { uids });
    // }

    // public async levelUp(uids: Array<string>, _lv: string) {
    //     const { ctx } = this;
    //     console.log('gm levelUp', uids, _lv);
    //     let lv = parseInt(_lv);
    //     if (isNaN(lv)) return ctx.service.utils.resResult(STATUS.WRONG_PARMS);
    //     for (let roleId of uids) {
    //         let exp = getExpByLv(lv - 1);
    //         await RoleModel.levelup(roleId, lv, exp ? exp.sum : 0);
    //     }

    //     return ctx.service.utils.resResult(STATUS.SUCCESS, { uids });
    // }

    //   public async getHeroList(roleId: string) {
    //     const {ctx} = this;
    //     let herolist = await HeroModel.findByRole(roleId);
    //     let defense = await PvpDefenseModel.findByRoleId(roleId);

    //     let result = Array<Hero>();
    //     for(let hero of herolist) {
    //         if(defense) {
    //             let {heroes = []} = defense;
    //             let curHero = heroes.find(cur => cur.actorId == hero.hid);
    //             if(!curHero) {
    //                 result.push(hero);
    //             }
    //         } else{
    //             result.push(hero);
    //         }
    //     }

    //     return ctx.service.utils.resResult(STATUS.SUCCESS, {
    //         heroes: result
    //     })
    //   }


    /**
     * 根据类型等搜索玩家
     */
    public async getHeroList(page: number, pageSize: number, sortField: string, sortOrder: string, form: SearchHeroParam) {
        const { ctx } = this;

        const heroes = await HeroModel.findByCondition(page, pageSize, sortField, sortOrder, form);
        const total = await HeroModel.countByCondition( form )
        
        let roleMap = new Map<string, RoleCeType>();
        for(let { roleId } of heroes) {
            if(!roleMap.has(roleId)) {
                let roleCe = await RoleCeModel.findByRoleId(roleId);
                roleMap.set(roleId, roleCe);
            }
        }
        let list = heroes.map(cur => {
            let roleCe = roleMap.get(cur.roleId);
            let obj = roleCe?.attributes?.find(ccur => ccur.hid == cur.hid);
            return {...cur, calculatedAttr: obj?.attrs||[], env: ctx.app.config.realEnv}
        })

        return ctx.service.utils.resResult(STATUS.SUCCESS, { list, total })
    }


    public async deleteItem(roleIdAndIds: string[]) {
        console.log('enter Auth deleteItem');
        const ctx = this.ctx;
        let map = new Map<string, number[]>();
        for (let roleIdAndId of roleIdAndIds) {
            let [roleId, idStr] = roleIdAndId.split('|');
            if (isNaN(parseInt(idStr))) return ctx.service.utils.resResult(STATUS.WRONG_PARMS);

            let id = parseInt(idStr);
            let cur = map.get(roleId);
            if (!cur) {
                cur = new Array<number>();
                map.set(roleId, cur);
            }
            cur.push(id);
        }

        for (let [roleId, ids] of map) {
            await ItemModel.deletebyRoleAndIds(roleId, ids);
        }

        return ctx.service.utils.resResult(STATUS.SUCCESS);
    }


    // public async setItemCount(roleIdAndIds: string[], count: number) {
    //     console.log('enter Auth setItemCount');
    //     const ctx = this.ctx;
    //     let map = new Map<string, number[]>();
    //     for (let roleIdAndId of roleIdAndIds) {
    //         let [roleId, idStr] = roleIdAndId.split('|');
    //         if (isNaN(parseInt(idStr))) return ctx.service.utils.resResult(STATUS.WRONG_PARMS);

    //         let id = parseInt(idStr);
    //         let cur = map.get(roleId);
    //         if (!cur) {
    //             cur = new Array<number>();
    //             map.set(roleId, cur);
    //         }
    //         cur.push(id);
    //     }

    //     for (let [roleId, ids] of map) {
    //         await ItemModel.updateCountByRoleAndIds(roleId, ids, count);
    //     }

    //     return ctx.service.utils.resResult(STATUS.SUCCESS);
    // }

    // public async setHeroLv(roleIdAndHids: string[], _hlv: string) {

    //     try {
    //         console.log('gm setHeroLv', roleIdAndHids, _hlv);
    //         const ctx = this.ctx;
    //         let hlv = parseInt(_hlv);
    //         if (isNaN(hlv)) return ctx.service.utils.resResult(STATUS.WRONG_PARMS);

    //         for (let roleIdAndHid of roleIdAndHids) {
    //             let [roleId, hidStr] = roleIdAndHid.split('|');
    //             if (isNaN(parseInt(hidStr))) return ctx.service.utils.resResult(STATUS.WRONG_PARMS);

    //             let hid = parseInt(hidStr);

    //             let hero = await HeroModel.findByHidAndRole(hid, roleId);
    //             console.log(hid, roleId, !!hero);
    //             if (!hero) continue;
    //             await calPlayerCeAndSave(HERO_SYSTEM_TYPE.LVUP, roleId, hero, { lv: hlv });
    //         }

    //         return ctx.service.utils.resResult(STATUS.SUCCESS);
    //     } catch (e) {
    //         console.error((<Error>e).stack)
    //     }
    // }

    // public async setHeroParam(roleIdAndHids: string[], star: number, colorStar: number, quality: number) {
    //     try {
    //         const ctx = this.ctx;
    //         if (typeof star != 'number'||typeof colorStar != 'number'||typeof quality != 'number') return ctx.service.utils.resResult(STATUS.WRONG_PARMS); 

    //         for (let roleIdAndHid of roleIdAndHids) {
    //             let [roleId, hidStr] = roleIdAndHid.split('|');
    //             if (isNaN(parseInt(hidStr))) return ctx.service.utils.resResult(STATUS.WRONG_PARMS);

    //             let hid = parseInt(hidStr);

    //             let hero = await HeroModel.findByHidAndRole(hid, roleId);
    //             console.log(hid, roleId, !!hero);
    //             if (!hero) continue;
    //             await calPlayerCeAndSave(HERO_SYSTEM_TYPE.LVUP, roleId, hero, { star, colorStar, quality });
    //         }

    //         return ctx.service.utils.resResult(STATUS.SUCCESS);
    //     } catch (e) {
    //         console.error((<Error>e).stack)
    //     }
    // }


    // public async setHeroJob(roleIdAndHids: string[], job: number) {
    //     try {
    //         const ctx = this.ctx;
    //         if(!gameData.job.has(job)) return ctx.service.utils.resResult(STATUS.WRONG_PARMS);

    //         for (let roleIdAndHid of roleIdAndHids) {
    //             let [roleId, hidStr] = roleIdAndHid.split('|');
    //             if (isNaN(parseInt(hidStr))) return ctx.service.utils.resResult(STATUS.WRONG_PARMS);

    //             let hid = parseInt(hidStr);

    //             let hero = await HeroModel.findByHidAndRole(hid, roleId);
    //             console.log(hid, roleId, !!hero);
    //             if (!hero) continue;
    //             await calPlayerCeAndSave(HERO_SYSTEM_TYPE.STAGEUP, roleId, hero, { job });
    //         }

    //         return ctx.service.utils.resResult(STATUS.SUCCESS);
    //     } catch (e) {
    //         console.error((<Error>e).stack)
    //     }
    // }

    /**
     * 根据类型等搜索道具
     */
    public async getItemList(page: number, pageSize: number, sortField: string, sortOrder: string, form: SearchItemParam) {
        const { ctx } = this;

        const items = await ItemModel.findByCondition(page, pageSize, sortField, sortOrder, form);
        const total = await ItemModel.countByCondition( form )

        let list = items.map(cur => {
            return {...cur, env: ctx.app.config.realEnv}
        })

        return ctx.service.utils.resResult(STATUS.SUCCESS, { list, total })
    }

    public async getGuildList(page: number, pageSize: number, sortField: string, sortOrder: string, form: SearchGuildParam) {
        const { ctx } = this;
        let redisClient: RedisClient = ctx.app.context.redisClient;

        const guilds = await GuildModel.findByCondition(page, pageSize, sortField, sortOrder, form);
        const total = await GuildModel.countByCondition( form )

        let list = [];
        for(let guild of guilds) {
            let rank = await redisClient.zrevrankAsync(`${REDIS_KEY.GUILD_LV_RANK}:${guild.serverId}`, guild.code);

            list.push({ ...guild, rank: rank == undefined? '未上榜': rank + 1, env: ctx.app.config.realEnv })
        }

        return ctx.service.utils.resResult(STATUS.SUCCESS, { list, total })
    }

    public async getMembersByGuildCode(code: string) {
        const { ctx } = this;
        let guild = await GuildModel.findByCode(code);
        if(!guild) return ctx.service.utils.resResult(STATUS.GUILD_NOT_FOUND);

        let userGuilds = await UserGuildModel.getListByGuild(code);
        let list = userGuilds.map(userGuild => ({ ...userGuild, env: ctx.app.config.realEnv }))

        return ctx.service.utils.resResult(STATUS.SUCCESS, { list })
    }

    public async getGiftCodeList(page: number, pageSize: number, sortField: string, sortOrder: string, form: SearchGiftCodeParam = {}) {
        const { ctx } = this;

        const list = await GiftCodeModel.findByCondition(page, pageSize, sortField, sortOrder, form);
        const total = await GiftCodeModel.countByCondition( form )
        return ctx.service.utils.resResult(STATUS.SUCCESS, {
            list: list.map(cur => ({...cur, env: ctx.app.config.realEnv })), total
        });
    }

    public async createAndGenerateGift(obj: any, count: number = 1) {
        const { ctx } = this;
        let params = new CreateGiftCode(obj);
        if(!isNumber(count) || !params.checkParams()) return ctx.service.utils.resResult(STATUS.WRONG_PARMS);

        let giftCode = await GiftCodeModel.createData(params);
        await GiftCodeDetailModel.generateMany(giftCode, count, ctx.user?.uid);
        return ctx.service.utils.resResult(STATUS.SUCCESS, giftCode);
    }

    public async updateGiftCode(id: number, obj: any) {
        const { ctx } = this;
        let params = new UpdateGiftCode(id, obj);
        if(!params.checkParams()) return ctx.service.utils.resResult(STATUS.WRONG_PARMS);

        const result = await GiftCodeModel.updateData(id, params, ctx.user?.uid);
        if(!result) return ctx.service.utils.resResult(STATUS.INTERNAL_ERR);
        return ctx.service.utils.resResult(STATUS.SUCCESS);
    }

    public async generateGiftCode(id: number, count: number) {
        const { ctx } = this;
        if(!isNumber(id) || !isNumber(count)) return ctx.service.utils.resResult(STATUS.WRONG_PARMS);

        let giftCode = await GiftCodeModel.findByGiftId(id);
        if(!giftCode) return ctx.service.utils.resResult(STATUS.DB_DATA_NOT_FOUND);
        await GiftCodeDetailModel.generateMany(giftCode, count, ctx.user?.uid);
        return ctx.service.utils.resResult(STATUS.SUCCESS, giftCode);
    }

    public async cancelGiftCode(id: number, isEnable: boolean) {
        const { ctx } = this;
        if(!isNumber(id)) return ctx.service.utils.resResult(STATUS.WRONG_PARMS);

        let giftCode = await GiftCodeModel.findByGiftId(id);
        if(!giftCode) return ctx.service.utils.resResult(STATUS.DB_DATA_NOT_FOUND);
        await GiftCodeModel.updateData(id, { isEnable }, ctx.user?.uid);
        return ctx.service.utils.resResult(STATUS.SUCCESS, giftCode);
    }

    public async getGiftCodeDetailFile(id: number, fileType: string) {
        const { ctx } = this;
        
        let giftCode = await GiftCodeModel.findByGiftId(id);
        if(!giftCode) return ctx.service.utils.resResult(STATUS.WRONG_PARMS);
        let giftCodeDetails = await GiftCodeDetailModel.findAllCodeByGiftId(giftCode.id, giftCode.generateCnt);

        if(fileType == 'txt') {
            let codes: string[] = [];
            for(let {code} of giftCodeDetails) {
                codes.push(code);
            }
            console.log(id, codes.join())

            ctx.set('Content-Type', 'application/octet-stream');
            return Buffer.from(codes.join('\n'));
        } else if(fileType == 'xls'){
            ctx.set('Content-Type', 'application/vnd.openxmlformats');
            return await this.generateExcelFromGiftCode(giftCodeDetails);
        }
    }

    private async generateExcelFromGiftCode(giftCodeDetails: GiftCodeDetail[]) {
        let workBook = new Excel.Workbook();
        let worksheet = workBook.addWorksheet('sheet1');
        let rows = giftCodeDetails.map(cur => [cur.code]);
        worksheet.addTable({
            name: 'table1',
            ref: 'A1',
            columns: [
              {name: '礼包码', filterButton: false},
            ],
            rows,
          });
          return await workBook.xlsx.writeBuffer();
    }

    public async getGiftCodeDetailList(page: number, pageSize: number, sortField: string, sortOrder: string, form: SearchGiftCodeDetailParam = {}) {
        const { ctx } = this;

        const list = await GiftCodeDetailModel.findByCondition(page, pageSize, sortField, sortOrder, form);
        const total = await GiftCodeDetailModel.countByCondition( form )
        return ctx.service.utils.resResult(STATUS.SUCCESS, {
            list: list.map(cur => ({...cur, env: ctx.app.config.realEnv })), total
        });
    }

    public async setWarRecord(roleId: string, warId: number) {
        const { ctx } = this;
        if(!isNumber(warId)) return ctx.service.utils.resResult(STATUS.WRONG_PARMS);
        if(warId < 104) return ctx.service.utils.resResult(STATUS.WRONG_PARMS, '不可以跳到序章以前')
        let dicWar = gameData.war.get(warId);
        if(!dicWar) return ctx.service.utils.resResult(STATUS.WRONG_PARMS);

        await this.setWarStarAndScript(roleId, dicWar);
        if(dicWar.warType == WAR_TYPE.TOWER) {
            await this.setTowerWar(roleId, dicWar);
        }
        return ctx.service.utils.resResult(STATUS.SUCCESS);
    }

    private async setTowerWar(roleId: string, dicWar: DicWar) {
        let towerLv = 1;
        for(let [lv, dicTower] of gameData.tower) {
            if(dicTower.warArray.indexOf(dicWar.war_id) != -1) {
                towerLv = lv; break;
            }
        }
        let role = await RoleModel.updateRoleInfo(roleId, { towerLv });
        await TowerRecordModel.deleteAccount(roleId);
        await TowerRecordModel.insertTowerRec(roleId, towerLv);
        await HangUpRecordModel.deleteAccount(roleId);
        await HangUpRecordModel.initRecord(roleId, role.roleName, towerLv);
    }

    public async setCreateTime(roleId: string, day: number) {
        const { ctx } = this;
        if(!isNumber(day) || day < 0) return ctx.service.utils.resResult(STATUS.WRONG_PARMS);

        let createTime = nowSeconds() - (day - 1) * 86400;

        let role = await RoleModel.updateRoleInfo(roleId, { createTime });
        if(!role) return ctx.service.utils.resResult(STATUS.WRONG_PARMS);
        
        return ctx.service.utils.resResult(STATUS.SUCCESS);
    }

    private async setWarStarAndScript(roleId: string, dicWar: DicWar) {
        let { warStar } = await RoleModel.findByRoleId(roleId);
        let deleteIds: number[] = [], myMaxWarId = 0;
        for(let i = 0; i < warStar.length; i++) {
            let { id, warType } = warStar[i];
            if(warType == dicWar.warType) {
                if(id >= dicWar.war_id) {
                    deleteIds.push(id);
                }
                if(id > myMaxWarId) {
                    myMaxWarId = id;
                }
            }
        }
        let newWarStar = warStar.filter(cur => {
            return deleteIds.indexOf(cur.id) == -1;
        });
        if(myMaxWarId < dicWar.war_id) {
            for(let id = myMaxWarId + 1; id < dicWar.war_id; id++) {
                let _dicWar = gameData.war.get(id)
                if(_dicWar && _dicWar.warType == dicWar.warType) {
                    newWarStar.push({ id, warType: _dicWar.warType, star: 0, stars: [] });
                }
            }
        }
        let preGkIndex = newWarStar.findIndex(cur => cur.id == dicWar.previousGk);
        console.log(dicWar.previousGk)
        if(dicWar.previousGk && preGkIndex == -1) {
            let _dicWar = gameData.war.get(dicWar.previousGk);
            if(_dicWar) {
                newWarStar.push({ id: _dicWar.war_id, warType: _dicWar.warType, star: 0, stars: [] });
            }
        }
        await RScriptRecordModel.deleteByWarType(roleId, dicWar.warType);
        let insertParams: DicWar[] = [];
        for(let [_, obj] of gameData.war) {
            if(dicWar.warType == obj.warType && obj.war_id < dicWar.war_id) {
                insertParams.push(obj);
            }
        }

        if(insertParams.length > 0) {
            await RScriptRecordModel.insertScripts(roleId, insertParams);
        }
        let role = await RoleModel.updateRoleInfo(roleId, { warStar: newWarStar });
        return role;
    }
}
