// 关卡表
import {decodeArrayListStr, parseGoodStr, parseNumberList, readFileAndParse} from '../util'
import { TRAIN_REWARD_TYPE, WAR_RELATE_TABLES, WAR_TYPE } from '../../consts';
import { isString } from 'underscore'
import { RewardInter } from '../interface';
export interface DicWar {

    // 关卡id
    readonly war_id: number;
    // 关卡固定奖励
    readonly fixReward: Array<{id: number, count: number}>;
    // 关卡条件奖励
    readonly conditionReward: Array<{id: number, count: number, condition: number}>;
    // 关卡随机奖励
    readonly randomReward: Array<{id: number, count: number, frequency: number}>;
    // 关卡类型
    readonly warType: number;
    // 关卡名
    readonly gk_name: string;
    // 章节id
    readonly chapter: number;
    // 关卡id
    readonly section: number;
    // 胜利后获得的君主经验
    readonly kingExp: number;
    // 进入战场所需的最低等级
    readonly lvLimited: number;
    // 消耗的体力
    readonly cost: number;
    // 前置关卡
    readonly previousGk: number;
    // 每日任务下的小类型
    readonly dailyType: number;
    // 寻宝匹配json
    readonly dispatchJsonId: number;
    // 镇念塔禁用角色
    readonly fobiddenCharactor: Array<{type: number, id: number}>;
    // 推荐战力
    readonly recommendedPower: number;
    // 远征随机buff
    readonly mapseid: number[];
    // 秘境类型
    readonly movePoint: number;
    // 战前剧本
    readonly scriptBefore: string;
    // 战后剧本
    readonly scriptAfter: string;
    // 练兵场胜利奖励
    readonly winReward: Map<number, number|RewardInter[]>;
    // 练兵场失败奖励
    readonly failReward: Map<number, number|RewardInter[]>;
    // 上场数量
    readonly minHeroNum: number;
    // 次级属性 关联
    readonly secondAttrLevel: number;
    // 显示
    readonly selectView: number;
    readonly level: number;
}

export interface DicComBattleReward {
    // 关卡固定奖励
    readonly captainReward: Array<{id: number, count: number}>;
    // 队友奖励
    readonly teammateReward: Array<{id: number, count: number}>;
    // 队长限时段增加奖励
    readonly captainTimeReward: Array<{id: number, count: number}>;
    // 队友限时段增加奖励
    readonly teammateTimeReward: Array<{id: number, count: number}>;
    // 队长军团加成奖励
    readonly captainTimeGuildReward: Map<number, {id: number, count: number}[]>;
    // 队友军团加成奖励
    readonly teammateTimeGuildReward: Map<number, {id: number, count: number}[]>;
}
export const dicWar = new Map<number, DicWar>();
export const dicWarPvp = new Array<DicWar>();
export const dicDailyWarByType = new Map<number, DicWar[]>();
export const dicHeroIdByWar = new Map<number, number>();
export const dicComBattleReward = new Map<number, DicComBattleReward>(); // warId => DicComBattleReward

export function loadWar() {
    dicWar.clear();
    dicDailyWarByType.clear();
    dicWarPvp.splice(0, dicWarPvp.length);
    dicHeroIdByWar.clear();
    dicComBattleReward.clear();
    for(let filename of WAR_RELATE_TABLES) {
        let arr = readFileAndParse(filename);
    
        arr.forEach(o => {
            o.fixReward = parseFixReward(o.fixReward);
            o.conditionReward = parseConditionReward(o.conditionReward);
            o.randomReward = parseRandomReward(o.RandomReward||o.randomReward);
            o.fobiddenCharactor = parseForbiddenChara(o.fobiddenCharactor);
            o.mapseid = parseNumberList(o.mapseid);
            if(o.script_id && isString(o.script_id)) {
                let scripts = o.script_id?.split('&')||[];
                for(let script of scripts) {
                    if(script.indexOf('R_') != -1) {
                        o.scriptBefore = script;
                    } else if (script.indexOf('RE_') != -1) {
                        o.scriptAfter = script;
                    }
                }
            }
    
            if(o.warType == WAR_TYPE.PVP) {
                dicWarPvp.push(o);
            } else if (o.warType == WAR_TYPE.DAILY) {
                if(!dicDailyWarByType.has(o.dailyType)) {
                    dicDailyWarByType.set(o.dailyType, []);
                }
                dicDailyWarByType.get(o.dailyType).push(o);
            } else if (o.warType == WAR_TYPE.GUILD_TRAIN) {
                o.winReward = parseTrainReward(o.winReward);
                o.failReward = parseTrainReward(o.failReward);
            } else if (o.warType == WAR_TYPE.COM_BATTLE) {
                let reward = {
                    captainReward: o.fixReward,
                    teammateReward: parseGoodStr(o.teammateReward),
                    captainTimeReward: parseGoodStr(o.time_captain_normalReward),
                    teammateTimeReward: parseGoodStr(o.time_normalReward),
                    captainTimeGuildReward: parseComBattleTimeReward(o.time_captain_guildReward),
                    teammateTimeGuildReward: parseComBattleTimeReward(o.time_guildReward),
                }
                dicComBattleReward.set(o.war_id, reward);
            }
            dicWar.set(o.war_id, o);
            if(!!o.heroId) dicHeroIdByWar.set(o.war_id, o.heroId);
            if(o.HeroNum) o.minHeroNum = parseInt(o.HeroNum.split('&')[0]);
        });
    }
}

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

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

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

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

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

function parseTrainReward(str: string) {
    let result = new Map<number, number|RewardInter[]>();
    if(!str) return result;
    let decodeArr = decodeArrayListStr(str);
    for(let [type, str1, str2] of decodeArr) {
        if(parseInt(type) == TRAIN_REWARD_TYPE.SCORE) {
            if(isNaN(parseInt(str1))) {
                throw new Error('data table format wrong');
            }
            if(!result.has(parseInt(type))) {
                result.set(parseInt(type), parseInt(str1));
            }
        } else if (parseInt(type) == TRAIN_REWARD_TYPE.ITEM) {
            if(isNaN(parseInt(str1)) || isNaN(parseInt(str2))) {
                throw new Error('data table format wrong');
            }
            if(!result.has(parseInt(type))) {
                result.set(parseInt(type), []);
            }
            (<RewardInter[]>result.get(parseInt(type))).push({ id: parseInt(str1), count: parseInt(str2) });
        }
    } 
    return result
}

function parseComBattleTimeReward(str: string) {
    let result = new Map<number, {id: number, count: number}[]>();
    if(!str) return result;
    let decodeArr = decodeArrayListStr(str);
    for(let i = 0; i < decodeArr.length; i++) {
        let [id, count] = decodeArr[i]
        result.set(i + 1, [{ id: parseInt(id), count: parseInt(count) }]);
    }
    return result;
}