import { PublicShared } from "../public/public";
import { getFightDPS, getPlayerMFDPS } from "./fightDPS";
import { isDropBuff, randNumber } from "./fightFun";
import { afterSkillType, buffDataType } from "./fightType";

export class RunAfterSkill {
    static run(skillinfo: afterSkillType, where?: string) {
        let toRole = skillinfo.toRole;
        // if (toRole.isDead) return;
        let skillconf = skillinfo.skillConf;
        let act = skillconf.act;

        if (!this['afterSkill_' + act]) console.log("未知的攻击后技能", act);
        return this['afterSkill_' + act](skillinfo, where);
    }

    static afterSkill_atkdamage(skillinfo: afterSkillType, where?: string) {
        let toRole = skillinfo.toRole;
        let fromRole = skillinfo.fromRole;
        let skillConf = skillinfo.skillConf;

        let pro = skillConf.data.pro;
        if (skillConf.data.gs) {
            pro = PublicShared.eval(skillConf.data.val, { slv: fromRole.skillLv });
        }

        let extData = { 'pro': pro };
        Object.assign(extData, skillConf.ext);


        if (skillConf.data.gs) {
            var dpsinfo = getPlayerMFDPS(fromRole, toRole, extData);
        } else {
            var dpsinfo = getFightDPS(fromRole, toRole, extData);
        }

        toRole.lastHitMe = skillinfo.fromRole;
        toRole.modifyHp(dpsinfo, {
            skillType: 'afterAtk',
            skillId: skillinfo.skillConf.skillid
        });

        return dpsinfo;
    }

    /**
     * 附加额外伤害
     * @param skillinfo
     * @param where
     */
    static afterSkill_atkmag(skillinfo: afterSkillType, where?: string) {
        let toRole = skillinfo.toRole;
        let fromRole = skillinfo.fromRole;
        let skillConf = skillinfo.skillConf;

        // 检测条件是存在异常buff
        if(skillConf.chkdata.debuffdpspro){
            if (!Object.keys(toRole.buffs).length) return
            for (let val of Object.values(toRole.buffs)) {
                let buff_type = val.data.skillConf.buff_type;
                if (!isDropBuff(buff_type)) return
            }
        }

        let pro = skillConf.data.pro;

        if (skillConf.data.gs) {
            pro = PublicShared.eval(skillConf.data.val, { slv: fromRole.skillLv });
        }

        let extData = { 'pro': pro };
        Object.assign(extData, skillConf.ext);


        if (skillConf.data.gs) {
            var dpsinfo = getPlayerMFDPS(fromRole, toRole, extData);
        } else {
            var dpsinfo = getFightDPS(fromRole, toRole, extData);
        }

        toRole.lastHitMe = skillinfo.fromRole;
        toRole.modifyHp(dpsinfo, {
            skillType: 'atkMag',
            skillId: skillinfo.skillConf.skillid
        });

        return dpsinfo;
    }

    static afterSkill_fanji(skillinfo: afterSkillType, where?: string) {
        let toRole = skillinfo.toRole;
        let fromRole = skillinfo.fromRole;
        if (fromRole.isCanAtk) return;
        if (toRole.hasbuff('wudi') || fromRole.isDead || toRole.isDead) return;
        let skillConf = skillinfo.skillConf;
        let extData = { 'pro': skillConf.data.pro };
        Object.assign(extData, skillConf.ext);
        let dpsinfo = getFightDPS(fromRole, toRole, extData);

        fromRole.fightControl.record({
            act: "fanji",
            fromRole: fromRole.rid,
            targets: [toRole.rid],
            skillId: skillinfo.skillConf.skillid,
            rolesInfo: {}
        });
        let recordIdx = fromRole.fightControl.getRecordIdx();
        let _rolesInfo = {};
        _rolesInfo[toRole.rid] = {};
        _rolesInfo[toRole.rid]['ov'] = toRole.getData("hp");

        toRole.lastHitMe = skillinfo.fromRole;
        toRole.modifyHp(dpsinfo, {
            skillType: 'fanji',
            skillId: skillinfo.skillConf.skillid
        });

        _rolesInfo[toRole.rid]['nv'] = toRole.getData("hp");
        _rolesInfo[toRole.rid]['miss'] = dpsinfo.miss;
        _rolesInfo[toRole.rid]['baoji'] = dpsinfo.baoji;
        fromRole.fightControl.fixRecordByIdx(recordIdx, { targets: [toRole.rid], rolesInfo: _rolesInfo });
    }

    static afterSkill_fanshang(skillinfo: afterSkillType, where?: string) {
        let dps = skillinfo?.emitData?.dps;
        if (!dps || dps > 0) return console.error("afterSkill_fanshang ==> no dps");
        let toRole = skillinfo.toRole;
        let fromRole = skillinfo.fromRole;

        let ov = toRole.getData('hp');
        toRole.fightControl.record({
            act: 'downHp',
            fromRole: toRole.rid,
            why: 'fanshang',
            buffId: "",
            ov: ov,
            nv: 0
        });
        let recordIdx = toRole.fightControl.getRecordIdx();
        dps *= (1 + toRole.getData('fanshang'));

        // 反伤倍率
        let randnum = skillinfo.skillConf.data.pro
        dps = dps * randnum

        let dpsinfo = { num: dps, dps: dps, miss: false, baoji: false, fromRole: fromRole, toRole: toRole };
        toRole.modifyHp(dpsinfo, {
            skillType: 'fangshang',
            skillId: skillinfo.skillConf.skillid
        });
        let nv = toRole.getData('hp');
        toRole.fightControl.fixRecordByIdx(recordIdx, { nv: nv });
    }

    static afterSkill_addhp(skillinfo: afterSkillType, where?: string) {
        let dps = skillinfo?.emitData?.dps;
        if (!dps || dps > 0) return console.error("afterSkill_fanshang ==> no dps");
        let toRole = skillinfo.toRole;
        let fromRole = skillinfo.fromRole;
        let pro = skillinfo.skillConf.data?.pro || 1;

        if (toRole.hasbuff('noaddhp')) return;

        let ov = toRole.getData('hp');
        toRole.fightControl.record({
            act: 'addHp',
            fromRole: toRole.rid,
            why: 'passive',
            buffId: "",
            ov: ov,
            nv: 0
        });
        let recordIdx = toRole.fightControl.getRecordIdx();
        dps *= pro;
        let dpsinfo = { num: dps, dps: dps, miss: false, baoji: false, fromRole: fromRole, toRole: toRole };
        toRole.modifyHp(dpsinfo, {
            skillType: '',
            skillId: skillinfo.skillConf.skillid
        });
        let nv = toRole.getData('hp');
        toRole.fightControl.fixRecordByIdx(recordIdx, { nv: nv });

    }

    static afterSkill_zhiliao(skillinfo: afterSkillType, where?: string) {
        let toRole = skillinfo.toRole;
        let fromRole = skillinfo.fromRole;
        let skillConf = skillinfo.skillConf;
        let pro = skillConf.data?.pro || 0;

        if (toRole.hasbuff("noaddhp")) return;

        let ov = toRole.getData('hp');
        let maxhp = skillConf.data?.skillid ? (toRole.fightControl.recordSkillDps[skillConf.data?.skillid] || 0) : toRole.getData('maxHp');
        toRole.fightControl.record({
            act: 'addHp',
            fromRole: toRole.rid,
            why: 'zhiliao',
            buffId: "",
            ov: ov,
            nv: 0
        });
        let recordIdx = toRole.fightControl.getRecordIdx();
        let dps = maxhp * pro;
        let dpsinfo = { num: dps, dps: dps, miss: false, baoji: false, fromRole: fromRole, toRole: toRole };
        toRole.modifyHp(dpsinfo, {
            skillType: '',
            skillId: skillConf.skillid
        });
        let nv = toRole.getData('hp');
        toRole.fightControl.fixRecordByIdx(recordIdx, { nv: nv });
    }

    /**
     * 追加DPS
     * @param skillinfo
     * @param where
     */
    static afterSkill_zjdps(skillinfo: afterSkillType, where?: string) {
        let toRole = skillinfo.toRole;
        let fromRole = skillinfo.fromRole;
        let skillConf = skillinfo.skillConf;
        let extData = { 'pro': skillConf.data.pro };
        Object.assign(extData, skillConf.ext);
        let dpsinfo = getFightDPS(fromRole, toRole, extData);
        toRole.lastHitMe = skillinfo.fromRole;


        let ov = toRole.getData('hp');
        toRole.fightControl.record({
            act: 'downHp',
            fromRole: toRole.rid,
            why: 'zjdps',
            buffId: "",
            ov: ov,
            nv: 0
        });
        let recordIdx = toRole.fightControl.getRecordIdx();
        toRole.modifyHp(dpsinfo, {
            skillType: 'zjdps',
            skillId: skillinfo.skillConf.skillid
        });
        toRole.fightControl.fixRecordByIdx(recordIdx, { nv: toRole.getData('hp') });
    }

    static afterSkill_buff(skillinfo: afterSkillType, where?: string) {
        let toRole = skillinfo.toRole;
        let buffdata: buffDataType = skillinfo;
        buffdata.buffid = skillinfo.skillConf.skillid;
        let buff_type = skillinfo.skillConf.buff_type;
        //检查是否有buff<badbuffdrop> 免疫减益buff
        // if (toRole.hasbuff('badbuffdrop') && isDropBuff(sxleixing)) {
        if (toRole.hasbuff('badbuffdrop') && isDropBuff(buff_type)) {
            let pro = toRole.getBuffByType('badbuffdrop')[0].data.skillConf.xiaoguocanshu?.pro || 0;
            if (randNumber() > pro) return;
        }
        toRole.addBuff(buffdata);
    }

    static afterSkill_fuhuo(skillinfo: afterSkillType, where?: string) {
        let toRole = skillinfo.toRole, fromRole = skillinfo.fromRole;
        let skillConf = skillinfo.skillConf;
        let pro = skillConf.data.pro;
        let maxnums = skillConf.checkData?.maxnum || 1;
        if (fromRole.activeResurrect >= maxnums) return;
        fromRole.activeResurrect++;

        toRole.roleData.dead = false;
        let maxhp = toRole.getData('maxHp');
        let hp = Math.floor(maxhp * pro);
        toRole.setData('hp', hp);

        toRole.fightControl.record({
            act: 'fuhuo',
            fromRole: fromRole.rid,
            target: toRole.rid,
            nv: hp
        });
    }

    static afterSkill_chongsheng(skillinfo: afterSkillType, where?: string) {
        let toRole = skillinfo.toRole, fromRole = skillinfo.fromRole;
        let skillConf = skillinfo.skillConf;
        let pro = skillConf.data.pro;
        let maxnums = skillConf.checkData?.maxnum || 1;
        if (fromRole.activeResurrect >= maxnums) return;
        fromRole.activeResurrect++;

        toRole.roleData.dead = false;
        let maxhp = toRole.getData('maxHp');
        let hp = Math.floor(maxhp * pro);

        toRole.fightControl.record({
            act: 'chongsheng',
            fromRole: fromRole.rid,
            target: toRole.rid,
            nv: hp
        });
        skillinfo.toRole.fightControl.event.once("fightEvent_atkOver", () => {
            toRole.setData('hp', hp);
        });
    }

    static afterSkill_bisha(skillinfo: afterSkillType, where?: string) {
        let toRole = skillinfo.toRole, fromRole = skillinfo.fromRole;
        let skillConf = skillinfo.skillConf;
        let extData = { 'pro': skillConf.data.pro };
        Object.assign(extData, skillConf.ext);

        let chkData = skillConf.chkdata;
        let randnum = chkData.randnum;
        if (toRole.fightControl.fightType == chkData.fightType && toRole.hasbuff('xuanyuan') && randNumber() <= randnum) {

            let dpsinfo = getFightDPS(fromRole, toRole, extData);
            toRole.lastHitMe = skillinfo.fromRole;
            //直接斩杀
            let toHp = toRole.getData('hp');
            dpsinfo.dps = -toHp;
            dpsinfo.num = -toHp;

            toRole.modifyHp(dpsinfo, {
                skillType: 'afterAtk',
                skillId: skillinfo.skillConf.skillid
            });
            return dpsinfo;
        }
    }

    static afterSkill_qusan(skillinfo: afterSkillType, where?: string) {
        let toRole = skillinfo.toRole, fromRole = skillinfo.fromRole;
        for (let key in toRole.buffs) {
            let buff_type = toRole.buffs[key].data.skillConf.buff_type;
            if (isDropBuff(buff_type)) {
                toRole.buffs[key].clear('clear_qusan');
            }
        };
    }

}