import { ComAttackable } from "../components/ComAttackable";
import { ComBeAttacked } from "../components/ComBeAttacked";
import { ComMonitor } from "../components/ComMonitor";
import { ComRoleConfig } from "../components/ComRoleConfig";
import { ComTransform } from "../components/ComTransform";
import { ECSSystem } from "../lib/ECSSystem";
import { ECSWorld, GenFillterKey } from "../lib/ECSWorld";

const FILTER_ATTACKABLE = GenFillterKey([ComTransform, ComAttackable, ComRoleConfig]);
const FILTER_BEATTACKED = GenFillterKey([ComBeAttacked]);
export class SysAttack extends ECSSystem {
    /** 连接 */
    public onAdd(world: ECSWorld): void {

    }
    /** 断开连接 */
    public onRemove(world: ECSWorld): void {

    }
    /** 添加实体 */
    public onEntityEnter(world: ECSWorld, entity: number): void {

    }
    /**  */
    public onEntityLeave(world: ECSWorld, entity: number): void {
        let filter = world.getFilter(FILTER_ATTACKABLE);
        // 判断当前monitor是否
        filter.entities.forEach((value: boolean, otherEntity: number) => {
            let comBeAttacked = world.getComponent(otherEntity, ComBeAttacked);
            if(!comBeAttacked) return ;
            if(comBeAttacked.attacker == entity) comBeAttacked.attacker = -1;
        });
    }
    /** 更新 */
    public onUpdate(world: ECSWorld, dt: number): void {
        let filter = world.getFilter(FILTER_ATTACKABLE);
        filter.walk((entity: number) => {
            let comTransSelf = world.getComponent(entity, ComTransform);
            let comAttackable = world.getComponent(entity, ComAttackable);
            let comRoleConfigSelf = world.getComponent(entity, ComRoleConfig);
            if(!comAttackable.dirty) return ;

            comAttackable.countDown -= dt;
            if(comAttackable.countDown <= 0) {
                comAttackable.dirty = false;
                for(const entityOther of comAttackable.willHurts) {
                    let comBeAttacked = world.getComponent(entityOther, ComBeAttacked);
                    if(comBeAttacked && comBeAttacked.attacker == entity) comBeAttacked.attacker = -1;
                }
                comAttackable.willHurts.length = 0;
            }

            let limitX = comTransSelf.x + Math.sign(comTransSelf.dir.x) * comAttackable.hurtArea.x;
            let minX = Math.min(comTransSelf.x, limitX);
            let maxX = Math.max(comTransSelf.x, limitX);
            let minY = comTransSelf.y - comAttackable.hurtArea.y;
            let maxY = comTransSelf.y + comAttackable.hurtArea.y;

            let _checkBeAttack = (entityOther: number) => {
                if(entity == entityOther) return false;
                let comRoleConfigOther = world.getComponent(entityOther, ComRoleConfig);
                if(!comRoleConfigOther || comRoleConfigOther.team == comRoleConfigSelf.team) return false;
                let comTransOther = world.getComponent(entityOther, ComTransform);
                if(comTransOther.x < minX || comTransOther.x > maxX || Math.abs(comTransOther.y - comTransSelf.y) >= comAttackable.hurtArea.y) {
                    return false;
                }
                return true
            }

            comAttackable.debugInfo = {
                points: [cc.v2(minX, minY), cc.v2(maxX, minY), cc.v2(maxX, maxY), cc.v2(minX, maxY)],
                color: cc.Color.RED,
            };

            // 即将攻击未完成, 并且处于即将攻击时间段
            if(!comAttackable.willHurtFrameCompleted && comAttackable.countDown <= comAttackable.willHurtFrame) {
                comAttackable.willHurtFrameCompleted = true;
                world.getFilter(FILTER_BEATTACKED).walk((entityOther: number) => {
                    if(!_checkBeAttack(entityOther)) return ;
                    let comBeAttackedOther = world.getComponent(entityOther, ComBeAttacked);
                    comBeAttackedOther.attacker = entity;
                    comAttackable.willHurts.push(entityOther)

                    return false;
                })
            }

            if(!comAttackable.hurtFrameCompleted && comAttackable.countDown <= comAttackable.hurtFrame) {
                comAttackable.hurtFrameCompleted = true;
                world.getFilter(FILTER_BEATTACKED).walk((entityOther: number) => {
                    let comBeAttacked = world.getComponent(entityOther, ComBeAttacked);
                    if(comBeAttacked && comBeAttacked.attacker == entity) comBeAttacked.attacker = -1;
                    if(!_checkBeAttack(entityOther)) return ;
    
                    let comRoleConfigOther = world.getComponent(entityOther, ComRoleConfig);
                    
                    // 扣血
                    if(!comRoleConfigOther || comRoleConfigOther.nowHP <= 0) return ;
                    comRoleConfigOther.lastHP = comRoleConfigOther.nowHP;
                    comRoleConfigOther.nowHP -= comAttackable.attack;
                    comRoleConfigOther.HPDirty = true;
    
                    // 打断对方的攻击动作
                    let comAttackableOther = world.getComponent(entityOther, ComAttackable);
                    if(!comAttackableOther || comAttackableOther.countDown <= 0) return ;
                    comAttackableOther.hurtFrameCompleted = true;
                    comAttackableOther.countDown = 0.25;

                    let comMonitorOther = world.getComponent(entityOther, ComMonitor);
                    if(comMonitorOther.others.indexOf(entity) == -1) {
                        comMonitorOther.others[0] = entity;
                    }
                        
                    return false;
                });
            }
            
            return false;
        });
    }
}