import { ResLogin } from "../protocols/user/PtlLogin";
import { HeroShared } from "../public/hero";
import { FightControl } from "./fightCntrol";
import { joinFightData } from "./fightType";

export function countAttr(from: joinFightData) {
    Object.values(from.roles).forEach(role => {
        role.attr = HeroShared.getHeroBasicAttr(role, from.player);
    });
}

export async function test() {

    new FightControl([formatNpcData(1), formatNpcData(1)]);
    // let players = await G.mongodb.collection('user').find().toArray();
    // let heros = await G.mongodb.collection('hero').find().toArray();
    // new FightControl(Array(2).fill(1).map(() => {

    //     let obj = {};
    //     let roles = Array(6).fill(1).map(() => {
    //         let hero = G.mongodb.conversionIdObj(heros.random());
    //         return Object.assign(hero, {
    //             attr: HeroShared.getHeroBasicAttr(hero, players.random())
    //         });

    //     });
    //     roles.forEach((r, p) => obj[p + 1] = r);
    //     return {
    //         player: players.random(),
    //         roles: obj
    //     };
    // }));
}

export function fixValue(val: number, min?: number, max?: number) {
    if (min && val < min) val = min;
    if (max && val > max) val = max;
    return val;
}

export function getSkillConf(skillid: string | number) {
    // if(G.config.debug) console.log(skillid)
    let v = null;
    if (G.gc.skill_atk[skillid]) {
        v = G.gc.skill_atk[skillid];
    } else if (G.gc.skill_buff[skillid]) {
        v = G.gc.skill_buff[skillid];
    } else if (G.gc.skill_passive[skillid]) {
        v = G.gc.skill_passive[skillid];
    } else if (G.gc.skill_afteratk[skillid]) {
        v = G.gc.skill_afteratk[skillid];
    }
    if (!v) {
        return console.error('###没有这个技能-->', skillid);
    }
    return JSON.parse(JSON.stringify(v));
}

export function randomSkill(skillObj: k_v<number>) {
    let randomArr = [];
    for (let key in skillObj) {
        let num = skillObj[key] * 100;
        randomArr = randomArr.concat(Array(num).fill(key));
    }
    var randomValue = randomArr[Math.floor(Math.random() * randomArr.length)];
    return randomValue;

}

export function randNumber(under?: number, over?: number) {
    switch (arguments.length) {
        case 0:
        case 1:
            return Math.random();
        case 2:
            return Math.random() * (over - under) + under;
        default:
            return 0;
    }
}

export function isDropBuff(buff_type: number) {
    return buff_type == 2 || buff_type == 3;

}

/**格式化npc配置为战斗数据 */
export function formatNpcData(npcId: string | number, fixData: Partial<ResLogin['gud']> = {}, lv?: number): joinFightData {
    return createNpc(npcId, fixData, lv);
}

function randomName(name: string) {
    let f = Math.random() >= .5;
    let b = Math.random() >= .5;

    return (f ? Object.values(G.gc.name).random().qian : '') + name + (b ? Object.values(G.gc.name).random().hou : '');
}

export function createNpc(npcId: string | number, fixData: Partial<ResLogin['gud']> = {}, lv?: number) {
    let npcConf = G.gc.npc[npcId];
    let npcList = npcConf.npclist;
    let dataArr = npcList.split('#').map(str => {
        let ops = str.split('_');
        return {
            heroId: ops[0],
            lv: lv || Number(ops[1]),
            countId: ops[2]
        };
    });
    const data: joinFightData = {
        player: {
            lv: dataArr[0].lv,
            head: {
                id: dataArr[0].heroId,
                time: -1
            },
            uid: `npc_${npcId}`,
            ghName: npcConf.ghname,
            name: G.gc.hero[dataArr[0].heroId].name,
            npcname: npcConf.npcname,
            isNpc: true
        },
        roles: Object.fromEntries(dataArr.map((d, i) => [i + 1, function () {

            let { id, atk, def, mindps, maxdps, hp, speed, ...ops } = G.gc.armyattr[d.countId];
            let buff = HeroShared.getHeroBasicAttr({ heroId: d.heroId, lv: d.lv });

            buff.hp = Math.floor(((Math.pow(d.lv + 20, 2) * (d.lv / 5 + 1)) - (d.lv + 3) * 100) * hp);
            buff.atk = Math.floor(atk);
            buff.def = Math.floor((Math.pow(d.lv + 14, 2) - 190) * def);
            buff.speed = Math.floor(d.lv * 1.4 * speed);
            buff.mindps = Math.floor(Math.pow(d.lv + 1, 1.8) * 7.5 * mindps);
            buff.maxdps = Math.floor(Math.pow(d.lv + 1, 1.8) * 9 * mindps);

            Object.assign(buff, ops);

            for (let k in buff) {
                if (k.indexOf('pro') == -1) continue;
                let buffKey = k.replace('pro', '');
                if (buff[buffKey]) {
                    buff[buffKey] += buff[buffKey] * buff[k];
                    buff[k] = 0;
                }
            }

            HeroShared.amendAttr(buff);

            buff.maxHp = buff.hp;
            return {
                attr: buff,
                ...d,
                lv: (npcConf.npcLv ? npcConf.npcLv[i]: 0) || d.lv,
                isBoss: !!npcConf.isboss,
                trueLv: d.lv || (npcConf.npcLv ? npcConf.npcLv[i]: 0)
            };

        }()]))
    };

    data.player.power = Object.values(data.roles).map(role => HeroShared.computeHeroZhanLi(role.attr)).reduce((a, b) => a + b);

    Object.assign(data.player, fixData);

    return data;
}