import {getSkillConf} from "../fightFun";
import {afterSkillType, EmitDataType, passiveChkType} from "../fightType";

/**
 *
 * @param passiver 被动的持有者
 * @param toRole 触发者
 * @param chkData
 */
// function _checkSidePassiveSkill(passiver: Role, toRole: FightObj, chkData: chkDataType) {
//     let filterFunc: (role: Role) => boolean
//     switch (chkData.side) {
//         case -1:
//             filterFunc = function (role) {
//                 return passiver == role;
//             };
//             break;
//         case 1:
//             filterFunc = function (role) {
//                 return role == toRole
//             }
//             break
//         default:
//             break;
//     }

//     let roles = [].concat(toRole);
//     var isSame = (callback: Function) => {
//         for (var i = 0; i < roles.length; i++) {
//             if (callback(roles[i])) {
//                 return true;
//             }
//         }
//         return false;
//     }
//     return isSame(filterFunc);
// }

// function _checkSide(this: passiveChkType) {
//     let chkdata = this.chkdata;
//     let emitData = this.emitData;
//     if (chkdata.side == undefined) return true;

//     // const passiveSkillArr = ['byatk', 'startatk', 'masterSkills'];

//     // if (passiveSkillArr.indexOf(chkdata.when) != -1) {
//     return _checkSidePassiveSkill(this.toRole, emitData.toRole, chkdata);
//     // } else {

//     // }

//     return true;

// };


function checkEmit(this: passiveChkType) {
    let isEmit = false;
    let chkData = this.chkdata;
    if (Object.keys(chkData).length == 0) return isEmit;

    let passiver = this.toRole;
    let toRole = this.emitData.toRole;

    //这些条件可以后续添加
    // if (_checkSide.call(this)) return true;

    if (chkData.side == -1 && passiver == toRole) isEmit = true;
    else if (chkData.side == 1 && passiver.roleData.side != toRole.roleData.side) isEmit = true;

    if (chkData.atkTar) {
        if (passiver != this.emitData.fromRole) isEmit = false;
    }
    if (chkData.isctrl == 1) {
        if (!passiver.hasbuff("xuanyun")) isEmit = false;
    }
    if (chkData.islong == 0) {
        let triggerSkill = getSkillConf(this.emitData.skillId)
        if (triggerSkill?.ext?.islong != 0) isEmit = false

    } else if (chkData.islong == 1) {
        let triggerSkill = getSkillConf(this.emitData.skillId)
        if (triggerSkill?.ext?.islong != 1) isEmit = false
    }

    return isEmit;
}

let idx = 0;

export class PassiveSkillBase {
    _passiveId = '';
    /**触发次数 */
    _triggerCount = 0;
    skillConf: k_v<any>;
    _timers: NodeJS.Timeout[] = [];
    _checkFunc: (data: EmitDataType) => void;
    /** 生效的剩余回合数 */
    remainingRounds = 0;

    constructor(public skillInfo: afterSkillType) {
        idx++;
        this._passiveId = 'passiveSkill_' + idx;
        this.skillConf = this.skillInfo.skillConf;
    }
    release(){
        this.clear('release');
        this.skillConf = null;
        this._timers = null;
    }

    start() {
        this._initEvent();
        this._initHoldRounds();
    }

    _initEvent() {
        let _when = this.skillConf.chkdata.when;
        let toRole = this.skillInfo.toRole;
        // if (_when == 'ontime') {
        //     //定时触发 或者 频率触发
        //     this._whenOntime();
        // } else {
            this._checkFunc = (emitData) => {
                toRole.debug(() => {
                    console.log('### passiveskill checkEmit', 'fightEvent_' + _when, this.skillConf.skillid);
                });
                this.checkEmit(emitData);
            };
            toRole.fightControl.event.on('fightEvent_' + _when, this._checkFunc.bind(this), this);
        //}
    }

    checkEmit(emitData: EmitDataType) {
        //已经是反伤照成的伤害就不触发
        // let emitSkillConf = getSkillConf(emitData.skillId);
        if (emitData?.skillType == "fanji" || emitData?.skillType == "fangshang" /* || this.skillInfo.toRole.isDead */ || emitData?.fromRole?.isDead) return;
        //主角不触发被动
        if ((emitData.fromRole && emitData.fromRole?.rid?.indexOf?.('player') != -1) || emitData.toRole?.rid?.indexOf?.('player') != -1) return;

        if (!checkEmit.call({
            chkdata: this.skillConf.chkdata,
            emitData: emitData,
            /** 被动的持有者 */
            toRole: this.skillInfo.toRole
        })) {
            return;
        }
        ;

        this.doAtk?.(emitData);
        if (this.skillConf.round == -1) this.clear('round-1');
    }

    _initHoldRounds() {
        let toRole = this.skillInfo.toRole;
        this.remainingRounds = this.skillConf.round || 1;
        toRole.fightControl.event.on('fightEvent_roundNums', this.fightEvent_roundNums.bind(this), this);
        this.fightEvent_roundNums({turn: toRole.fightControl.roundNums});
    }

    fightEvent_roundNums(data: { turn: number; }) {
        if (this.remainingRounds == 0) {
            this.clear('round');
        }
        this.remainingRounds--;
    }

    //不能也不应该有这样的逻辑，这是个回合制游戏！
    // _whenOntime() {
    //     let time = this.skillConf.chkdata.time;
    //     if (!time) return;
    //     this._timers.push(setTimeout(() => {
    //         this.doAtk();
    //     }, time));
    // }

    // _doNextOntime() {
    //     let pinlvtime = this.skillConf.chkdata.pinlvtime;
    //     if (!pinlvtime) return;
    //     this._timers.push(setTimeout(() => {
    //         this.doAtk();
    //     }, pinlvtime));
    // }

    /** 清除执行次数限制的被动 */
    _clearOnceSkill() {
        let chkdata = this.skillConf.chkdata;
        if (chkdata.once && this._triggerCount > chkdata.once) {
            this.clear('once');
        }
    }

    doAtk(emitData?: EmitDataType) {
        this._triggerCount++;
        this._clearOnceSkill();
        //this._doNextOntime();
    }

    clear(why: string) {
        let _when = this.skillConf.chkdata.when;
        let toRole = this.skillInfo.toRole;
        if (this._checkFunc) {
            toRole.fightControl.event.off('fightEvent_' + _when, this._checkFunc, this);
            this._checkFunc = null;
            delete this._checkFunc;
        }
        toRole.fightControl.event.off('fightEvent_roundNums', this.fightEvent_roundNums, this);

        this._timers.forEach(v => {
            clearTimeout(v);
        });
        this._timers = null;
        delete this._timers;

        toRole.passiveSkills[this._passiveId] = null;
        delete toRole.passiveSkills[this._passiveId];
    }
}