// 物品表
import { decodeArrayListStr, readFileAndParse, parseGoodStr } from '../util'
import { FILENAME, ABI_TYPE} from '../../consts'
import { RewardInter } from '../interface';
const _ = require('lodash');

export interface SpecialMaterial {
    readonly ids: number[]; 
    readonly count: number;
}

export interface DicTeraph {
    // 等级
    readonly id: number;
    readonly index: number;
    readonly grade: number;

    readonly mainAttrMax: Map<number, number>; // 最大强化加成 id => value  18围内的id
    readonly mainAttrUp: Map<number, number>; // 每次强化加成 id => value  18围内的id

    readonly criRate: number;
    readonly criEffect: number;
    readonly upMaterial:Array<RewardInter>;
    
    readonly assiAttrValue:Map<number, number>; // 次级属性
    readonly basicAttrValue:Map<number, number>; // 主属性
    readonly upGradeMaterial:Array<RewardInter>;
}
export const dicTeraph = new Map<string, DicTeraph>();
export function loadTeraph() {
    dicTeraph.clear();
    
    let arr = readFileAndParse(FILENAME.DIC_TERAPH);
    
    type KeysEnum<T> = { [P in keyof Required<T>]: true };
    const DicTeraphKeys: KeysEnum<DicTeraph> = {
        id: true, 
        index: true,
        grade: true,
        mainAttrMax: true,
        mainAttrUp: true,
        criRate: true,
        criEffect: true,
        upMaterial: true,
        assiAttrValue: true, 
        basicAttrValue: true,
        upGradeMaterial: true, 
    }

    arr.forEach(o => {
        o.assiAttrValue = parseAttr(o.assiAttrValue);
        o.upGradeMaterial = parseGoodStr(o.upGradeMaterial);
        o.upMaterial = parseGoodStr(o.upMaterial); 
        o.mainAttrMax = parseMainAttrMax(o);
        o.mainAttrUp = parseMainAttrUp(o);
        o.basicAttrValue = parseBasicAttr(o);
        dicTeraph.set(o.index + '_' + o.grade, _.pick(o, Object.keys(DicTeraphKeys)));
    });
    
    arr = undefined;
}

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

function parseMainAttrMax(elem) {
    let result = new Map<number, number>();
    result.set(ABI_TYPE.ABI_HP, elem.hpMax - elem.hpBasis);
    result.set(ABI_TYPE.ABI_ATK, elem.atkMax - elem.atkBasis);
    result.set(ABI_TYPE.ABI_DEF, elem.defMax - elem.defBasis);
    result.set(ABI_TYPE.ABI_MDEF, elem.mdefMax - elem.mdefBasis);
    return result
}

function parseMainAttrUp(elem) {
    let result = new Map<number, number>();
    result.set(ABI_TYPE.ABI_HP, elem.hpUp);
    result.set(ABI_TYPE.ABI_ATK, elem.atkUp);
    result.set(ABI_TYPE.ABI_DEF, elem.defUp);
    result.set(ABI_TYPE.ABI_MDEF, elem.mdefUp);
    return result
}

function parseBasicAttr(elem) {
    let result = new Map<number, number>();
    result.set(ABI_TYPE.ABI_HP, elem.hpBasis);
    result.set(ABI_TYPE.ABI_ATK, elem.atkBasis);
    result.set(ABI_TYPE.ABI_DEF, elem.defBasis);
    result.set(ABI_TYPE.ABI_MDEF, elem.mdefBasis);
    return result
}