// 军团建筑物
import {readFileAndParse, parseGoodStr, decodeArrayListStr, parseNumberList} from '../util'
import { FILENAME } from '../../consts'
import { RewardInter } from '../interface';
const _ = require('lodash');

type KeysEnum<T> = { [P in keyof Required<T>]: true };
// 中军大帐
export interface DicCentreBase {
    // id
    readonly id: number;
    // 等级
    readonly level: number;
    // 最大人数
    readonly peopleNum: number;
    // 管理员人数
    readonly managerNum: number;
    // 每日最大可获得资金
    readonly maxFund: number;
    // 许愿的品质
    readonly wishgoodsHero: { quality: number, count: number }[]
}

const DicCenterKeys: KeysEnum<DicCentreBase> = {
    id: true,
    level: true,
    peopleNum: true,
    managerNum: true,
    maxFund: true,
    wishgoodsHero: true
};

// 炼器堂
export interface DicEquipProduceBase {
    // id
    readonly id: number;
    // 等级
    readonly level: number;
    // 可以研发的品质
    readonly quality: number;
}

const DicEquipProduceKeys: KeysEnum<DicEquipProduceBase> = {
    id: true,
    level: true,
    quality: true,
};

// 演武台
export interface DicBossBase {
    // id
    readonly id: number;
    // 等级
    readonly level: number;
    // boss等级
    readonly bossLevel: number;
    // 关卡id
    readonly wars: Array<{warId:number, bossHp: number, bossHpRatio:number}>;
    // 掉落的拍卖行奖励
    readonly rewards: number;
    // 
    readonly consume: number;
    // 团长开启的奖励
    readonly opencost: number;
    // 击杀奖励
    readonly killReward: RewardInter[];
    // 伤害加成奖励 参与奖励
    readonly basicReward: RewardInter[];
    // 伤害加成奖励 伤害贡献奖励
    readonly damageRewardTotal: RewardInter[];
    // boss血量系数，boss血量为中位数 * ratio
    readonly ratio: number;
    // 鼓舞次数
    readonly encourageSum: number;
    // 基础分红
    readonly basicDividend: number;
}

const DicBossKeys: KeysEnum<DicBossBase> = {
    id: true,
    level: true,
    bossLevel: true,
    wars: true,
    rewards: true,
    consume: true,
    opencost: true,
    killReward: true,
    basicReward: true,
    damageRewardTotal: true,
    ratio: true,
    encourageSum: true,
    basicDividend: true,
};

// 练兵场
export interface DicTrainBase {
    // id
    readonly id: number;
    // 等级
    readonly level: number;
    // 进阶等级
    readonly trainLevel: number;
    // 难度系数
    readonly difficultyRatio: number;
    // 据点奖励增长系数
    readonly judianRewardRatio: number;
    // 试炼id
    readonly trainIds: number[];
}

const DicTrainKeys: KeysEnum<DicTrainBase> = {
    id: true,
    level: true,
    trainLevel: true,
    difficultyRatio: true,
    judianRewardRatio: true,
    trainIds: true
};

// 捐献所
export interface DicDonateBase {
    // id
    readonly id: number;
    // 等级
    readonly level: number;
    // 捐献奖励
    readonly donateReward: Map<number, { id: number, rewardGood: RewardInter, rewardFund:number, cosume:RewardInter }>;
}

const DicDonateKeys: KeysEnum<DicDonateBase> = {
    id: true,
    level: true,
    donateReward: true,
};


export const dicStructureConsume = new Map<number, Map<number, number>>(); // 升级消耗 structureId => level => consume
export const dicCenterBase = new Map<number, DicCentreBase>(); // 中军大帐
export const dicEquipPriduceBase = new Map<number, DicEquipProduceBase>(); // 炼器堂
export const dicBossBase = new Map<number, DicBossBase>(); // 演武台
export const dicBossBaseByBossLv = new Map<number, DicBossBase>(); // 演武台 boss等级=>dic
export const dicTrainBase = new Map<number, DicTrainBase>(); // 练兵场
export const dicDonateBase = new Map<number, DicDonateBase>(); // 捐献所
export const maxMemberCnt = { max: 0 }; // 满配最大人数

export function loadStructure() {
    dicStructureConsume.clear();
    dicCenterBase.clear();
    dicEquipPriduceBase.clear();
    dicBossBase.clear();
    dicBossBaseByBossLv.clear();
    dicTrainBase.clear();
    dicDonateBase.clear();
    maxMemberCnt.max = 0;

    // 中军大帐
    let arrCenter = readFileAndParse(FILENAME.DIC_GUILD_STRUCTURE_CENTER);
    arrCenter.forEach(o => {
        setStructureConsume(o);
        if(o.peopleNum > maxMemberCnt.max) maxMemberCnt.max = o.peopleNum;
        o.maxFund = o.feeLimit;
        o.wishgoodsHero = parseWishGoods(o.wishgoodsHero)
        dicCenterBase.set(o.level, _.pick(o, Object.keys(DicCenterKeys)));
    });
    arrCenter = undefined;

    // 炼器堂
    let arrEquip = readFileAndParse(FILENAME.DIC_GUILD_EQUIP_PRODUCE_BASE);
    arrEquip.forEach(o => {
        setStructureConsume(o);
        dicEquipPriduceBase.set(o.level, _.pick(o, Object.keys(DicEquipProduceKeys)));
    });
    arrEquip = undefined;

    // 演武台
    let arrBoss = readFileAndParse(FILENAME.DIC_GUILD_BOSS_BASE);
    arrBoss.forEach(o => {
        setStructureConsume(o);
        o.wars = o.warIdHP.split('|').map((warStrs)=> {
            if (!warStrs) {
                return;
            }
            let warArr = warStrs.split('&');
            return { warId: parseInt(warArr[0]), bossHp: parseInt(warArr[1]), bossHpRatio: parseInt(warArr[2])}
        });
        o.killReward = parseGoodStr(o.killReward);
        o.basicReward = parseGoodStr(o.basicReward);
        o.damageRewardTotal = parseGoodStr(o.damageRewardTotal);
        dicBossBase.set(o.level, _.pick(o, Object.keys(DicBossKeys)));
        dicBossBaseByBossLv.set(o.bossLevel, _.pick(o, Object.keys(DicBossKeys)));
    });
    arrBoss = undefined;

    // 练兵场
    let arrTrain = readFileAndParse(FILENAME.DIC_GUILD_TRAIN_BASE);
    arrTrain.forEach(o => {
        setStructureConsume(o);
        o.trainIds = parseNumberList(o.shilianId);
        dicTrainBase.set(o.level, _.pick(o, Object.keys(DicTrainKeys)));
    });
    arrTrain = undefined;

    // 捐献所
    let arrDonate = readFileAndParse(FILENAME.DIC_GUILD_DONATE_BASE);
    arrDonate.forEach(o => {
        setStructureConsume(o);
        o.donateReward = parseDonateReward(o.donatevalue, o.honourReward, o.fundReward);
        dicDonateBase.set(o.level, _.pick(o, Object.keys(DicDonateKeys)));
    });
    arrDonate = undefined;

    // 升级消耗
    function setStructureConsume(o) {
        let map = dicStructureConsume.get(o.structureId);
        if(!map) map = new Map<number, number>();
        map.set(o.level, o.consume);
        dicStructureConsume.set(o.structureId, map);
    }
}

// {"type": number, "count": number} 
export function parseDonateValue(str: string) {
    let result = new Array<{id:number, type: number, count: number }>();
    if (!str) return result;
    let decodeArr = decodeArrayListStr(str);
    for (let [id, type, count] of decodeArr) {
        if (isNaN(parseInt(type)) || isNaN(parseInt(count))) {
            throw new Error('data table format wrong');
        }
        result.push({id: parseInt(id), type: parseInt(type), count: parseInt(count) });
    }
    return result
}

// {"fund": number, "active": number} 
export function parseDonateReward( donateStr: string, Goodstr: string, fundStr: string) {
    let result = new Map<number, { id: number, rewardGood: RewardInter, rewardFund:number, cosume:RewardInter }>();
    if (!donateStr) return result;
    let decodeArr = decodeArrayListStr(donateStr);
    let goods = parseGoodStr(Goodstr);
    let funds = fundStr.split('&');
    for (let [id, type, count] of decodeArr) {
        if (isNaN(parseInt(type)) || isNaN(parseInt(count))) {
            throw new Error('data table format wrong');
        }
        let donateId = parseInt(id);
        result.set(donateId, {id: donateId, cosume: { id: parseInt(type), count: parseInt(count)}, rewardGood: goods[donateId - 1], rewardFund: parseInt(funds[donateId - 1])});
    }
    return result;
}

// { "quality": number, "count": number}
export function parseWishGoods(str: string) {
    let result = new Array<{ quality: number, count: number }>();
    if (!str) return result;
    let decodeArr = decodeArrayListStr(str);
    for (let [quality, count] of decodeArr) {
        if ( isNaN(parseInt(quality))|| isNaN(parseInt(count))) {
            throw new Error('data table format wrong');
        }
        result.push({ quality: parseInt(quality), count: parseInt(count) });
    }
    return result
}