package net.bbsdbz.metalmax.entity.pumpkin_ghost;

import net.bbsdbz.metalmax.entity.ModFunc;
import net.bbsdbz.metalmax.projectiles.pumpkin_seed.PumpkinSeedEntity;
import net.bbsdbz.metalmax.reg.ModEntityReg;
import net.minecraft.network.syncher.EntityDataAccessor;
import net.minecraft.network.syncher.EntityDataSerializers;
import net.minecraft.network.syncher.SynchedEntityData;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.util.Mth;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.damagesource.DamageTypes;
import net.minecraft.world.entity.AnimationState;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.ai.attributes.AttributeSupplier;
import net.minecraft.world.entity.ai.attributes.Attributes;
import net.minecraft.world.entity.ai.goal.MeleeAttackGoal;
import net.minecraft.world.entity.ai.goal.target.HurtByTargetGoal;
import net.minecraft.world.entity.ai.goal.target.NearestAttackableTargetGoal;
import net.minecraft.world.entity.animal.Animal;
import net.minecraft.world.entity.monster.Monster;
import net.minecraft.world.entity.monster.Skeleton;
import net.minecraft.world.entity.monster.Zombie;
import net.minecraft.world.entity.npc.AbstractVillager;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.Level;
import org.joml.Math;


import java.util.ArrayList;

public class PumpkinGhostEntity extends Monster {

    // 基础属性
    public static float MAX_HEALTH = 100.0F;
    public static float MOVEMENT_SPEED = 0.55F;
    public static float ATTACK_DAMAGE = 10.0F;
    public static float ARMOR = 1.0F;
    public static float ARMOR_TOUGHNESS = 1.0F;

    public final int XP = 50;

    // 动画相关
    public int A01Hit = 0;
    public int A02Hit = 0;

    public int B01Hit = 0;
    public int B01Cd = 0;

    public int C01Hit = 0;
    public int C01Cd = 0;

    public final AnimationState idle_animations = new AnimationState();
    public final AnimationState walk_animations = new AnimationState();
    public final AnimationState a01_animations = new AnimationState();
    public final AnimationState a02_animations = new AnimationState();
    public final AnimationState b01_animations = new AnimationState();
    public final AnimationState c01_animations = new AnimationState();
    public final AnimationState ON_FIRE_animations = new AnimationState();

    public static final EntityDataAccessor<Boolean> IDLE_TF = SynchedEntityData.defineId(PumpkinGhostEntity.class, EntityDataSerializers.BOOLEAN);
    public static final EntityDataAccessor<Boolean> WALK_TF = SynchedEntityData.defineId(PumpkinGhostEntity.class, EntityDataSerializers.BOOLEAN);
    public static final EntityDataAccessor<Boolean> A01_TF = SynchedEntityData.defineId(PumpkinGhostEntity.class, EntityDataSerializers.BOOLEAN);
    public static final EntityDataAccessor<Boolean> A02_TF = SynchedEntityData.defineId(PumpkinGhostEntity.class, EntityDataSerializers.BOOLEAN);
    public static final EntityDataAccessor<Boolean> B01_TF = SynchedEntityData.defineId(PumpkinGhostEntity.class, EntityDataSerializers.BOOLEAN);
    public static final EntityDataAccessor<Boolean> B01_TEX_TF = SynchedEntityData.defineId(PumpkinGhostEntity.class, EntityDataSerializers.BOOLEAN);
    public static final EntityDataAccessor<Boolean> C01_TF = SynchedEntityData.defineId(PumpkinGhostEntity.class, EntityDataSerializers.BOOLEAN);
    public static final EntityDataAccessor<Boolean> ON_FIRE_TF = SynchedEntityData.defineId(PumpkinGhostEntity.class, EntityDataSerializers.BOOLEAN);

    public static final EntityDataAccessor<Integer> TICK = SynchedEntityData.defineId(PumpkinGhostEntity.class, EntityDataSerializers.INT);
    public static final EntityDataAccessor<Integer> ANIMATION_CD = SynchedEntityData.defineId(PumpkinGhostEntity.class, EntityDataSerializers.INT);

    // 数据同步
    public static final EntityDataAccessor<Float> f1 = SynchedEntityData.defineId(PumpkinGhostEntity.class, EntityDataSerializers.FLOAT);
    public static final EntityDataAccessor<Float> f2 = SynchedEntityData.defineId(PumpkinGhostEntity.class, EntityDataSerializers.FLOAT);

    //动画列表
    ArrayList<EntityDataAccessor<Boolean>> animationList = new ArrayList<>();


    public PumpkinGhostEntity(EntityType<? extends Monster> entityType, Level level) {
        super(entityType, level);
        this.regAnimationList();
        this.xpReward = XP;
        this.C01Cd = 100;
    }

    // 初始化实体数据
    @Override
    protected void defineSynchedData(SynchedEntityData.Builder builder) {
        super.defineSynchedData(builder);
        builder.define(IDLE_TF, true);
        builder.define(A01_TF, false);
        builder.define(A02_TF, false);
        builder.define(B01_TF, false);
        builder.define(B01_TEX_TF, false);
        builder.define(C01_TF, false);
        builder.define(WALK_TF, false);
        builder.define(ON_FIRE_TF, false);
        builder.define(TICK, 0);
        builder.define(ANIMATION_CD, 0);
        builder.define(f1, 0f);
        builder.define(f2, 0f);
    }

    // 动画添加进列表
    public void regAnimationList() {
        this.animationList.add(IDLE_TF);
        this.animationList.add(A01_TF);
        this.animationList.add(A02_TF);
        this.animationList.add(B01_TF);
        this.animationList.add(C01_TF);
        this.animationList.add(WALK_TF);
        this.animationList.add(ON_FIRE_TF);
    }

    // 动画开关
//    public void animationStart(EntityDataAccessor<Boolean> animationName) {
//        for (EntityDataAccessor<Boolean> entityDataAccessor : animationList) {
//            if (entityDataAccessor == animationName) {
//                this.entityData.set(animationName, true);
//            } else {
//                this.entityData.set(entityDataAccessor, false);
//            }
//        }
//    }

    public void animationStart(EntityDataAccessor<Boolean> animationName){
        ModEntityFunc.animationStart(this,animationList,animationName);
    }

    // 基础属性
    public static AttributeSupplier.Builder setAttr() {
        return Monster.createMonsterAttributes()
                .add(Attributes.MAX_HEALTH, PumpkinGhostEntity.MAX_HEALTH)
                .add(Attributes.MOVEMENT_SPEED, PumpkinGhostEntity.MOVEMENT_SPEED)
                .add(Attributes.ATTACK_DAMAGE, PumpkinGhostEntity.ATTACK_DAMAGE)
                .add(Attributes.ARMOR, PumpkinGhostEntity.ARMOR)
                .add(Attributes.ARMOR_TOUGHNESS, PumpkinGhostEntity.ARMOR_TOUGHNESS)
                .add(Attributes.KNOCKBACK_RESISTANCE, 0.3F)
                .add(Attributes.STEP_HEIGHT, 1.5F);
    }

    // 基础Ai
    @Override
    protected void registerGoals() {
        super.registerGoals();
        this.targetSelector.addGoal(0, new HurtByTargetGoal(this));
//        this.targetSelector.addGoal(0, new WaterAvoidingRandomStrollGoal(this, this.getAttributeValue(Attributes.MOVEMENT_SPEED)));
//        this.goalSelector.addGoal(1, new MeleeAttackGoal(this, 0.5, false));
//        this.goalSelector.addGoal(7, new RandomLookAroundGoal(this));
        this.targetSelector.addGoal(1, new NearestAttackableTargetGoal<>(this, ServerPlayer.class, true));
        this.targetSelector.addGoal(2, new NearestAttackableTargetGoal<>(this, Player.class, true));
        this.targetSelector.addGoal(3, new NearestAttackableTargetGoal<>(this, AbstractVillager.class, false));
        this.targetSelector.addGoal(4, new NearestAttackableTargetGoal<>(this, Animal.class, false));

        this.targetSelector.addGoal(5, new NearestAttackableTargetGoal<>(this, Zombie.class, true));
        this.targetSelector.addGoal(5, new NearestAttackableTargetGoal<>(this, Skeleton.class, true));
    }


    // 限伤
    @Override
    public boolean hurt(DamageSource source, float amount) {
        this.setDeltaMovement(
                this.getDeltaMovement().x / 2F,
                this.getDeltaMovement().y - 5F,
                this.getDeltaMovement().z / 2F);
        if (this.random.nextFloat() <= 0.1f) {
            if (!source.is(DamageTypes.FELL_OUT_OF_WORLD) && !source.is(DamageTypes.GENERIC_KILL)) {
                if (amount >= this.getMaxHealth() * 0.8f) {
                    return super.hurt(source, this.getMaxHealth() * 0.8f);
                }
            }
        }
        return super.hurt(source, amount);
    }

    @Override // 取消墙体窒息伤害
    public boolean isInWall() {
        return false;
    }

//    @Override
//    public boolean isInLava() {
//        return false;
//    }

    @Override // 是否免疫摔伤
    public boolean causeFallDamage(float fallDistance, float multiplier, DamageSource damageSource) {
        return false;
    }

//    @Override // 是否在实体上渲染着火效果
//    public boolean displayFireAnimation() {
//        return false;
//    }

    @Override
    public void tick() {
        super.tick();

        //服务端
        if (!this.level().isClientSide()) {
            if (this.getTarget() != null) {
                ModEntityFunc.lookTarget(this,this.getTarget(),f1,f2);
                if (!entityData.get(WALK_TF)&&!this.isOnFire()) {
                    this.setYRot(entityData.get(f1));
                    this.setYBodyRot(entityData.get(f2));
                    this.setYRot(Mth.rotLerp(0.5f, this.yRotO, this.getYRot()));
                    this.setYBodyRot(Mth.rotLerp(0.5f, this.yBodyRotO, this.yBodyRot));
                }
            }
            this.mode();

            if (this.entityData.get(ANIMATION_CD) == 5) {
                this.setDeltaMovement(0, -1, 0);
                this.getNavigation().stop();
            }
            this.isIdle(IDLE_TF, ANIMATION_CD);
            this.attackTickCount();
        }

        // 客户端
        if (this.level().isClientSide()) {
            this.setupAnimationStates();
            if (!entityData.get(WALK_TF)&&!this.isOnFire()) {
                this.setYRot(entityData.get(f1));
                this.setYBodyRot(entityData.get(f2));
                this.setYRot(Mth.rotLerp(0.5f, this.yRotO, this.getYRot()));
                this.setYBodyRot(Mth.rotLerp(0.5f, this.yBodyRotO, this.yBodyRot));
            }

            this.setYRot(Mth.rotLerp(0.5f, this.yRotO, this.getYRot()));
            this.setYBodyRot(Mth.rotLerp(0.5f, this.yBodyRotO, this.yBodyRot));

//            this.setYRot(entityData.get(f1));
//            this.setYBodyRot(entityData.get(f2));
        }
    }

    // 动画播放器
    private void setupAnimationStates() {

        if (this.entityData.get(IDLE_TF)) {
            this.idle_animations.startIfStopped(tickCount);
        } else {
            this.idle_animations.stop();
        }

        if (this.entityData.get(WALK_TF)) {
            this.walk_animations.startIfStopped(tickCount);
        } else {
            this.walk_animations.stop();
        }

        if (this.entityData.get(ON_FIRE_TF)) {
            this.ON_FIRE_animations.startIfStopped(tickCount);
        } else {
            this.ON_FIRE_animations.stop();
        }

        if (this.entityData.get(A01_TF)) {
            this.a01_animations.startIfStopped(tickCount);
        } else {
            this.a01_animations.stop();
        }

        if (this.entityData.get(A02_TF)) {
            this.a02_animations.startIfStopped(tickCount);
        } else {
            this.a02_animations.stop();
        }

        if (this.entityData.get(B01_TF)) {
            this.b01_animations.startIfStopped(tickCount);
        } else {
            this.b01_animations.stop();
        }

        if (this.entityData.get(C01_TF)) {
            this.c01_animations.startIfStopped(tickCount);
        } else {
            this.c01_animations.stop();
        }
    }

    // 测算距离 XYZ
    public float  disV3(){
        return ModEntityFunc.disV3(this,this.getTarget());
    }
//    public float disV3(Entity TargetEntity) {
//        if (TargetEntity == null) {
//            return 0;
//        }
//        return this.distanceTo(TargetEntity);
//    }

    // 测算距离 XZ
    public float disV2(Entity TargetEntity) {
        if (TargetEntity == null) {
            return 0;
        }
        float f = (float) (this.getX() - TargetEntity.getX());
        float f1 = (float) (this.getZ() - TargetEntity.getZ());
        return Mth.sqrt(f * f + f1 * f1);
    }

    // 跳跃判断
    protected boolean isJump() {
        if (this.getTarget() != null) {
//            float f = ((float) (this.getTarget().getY() - (this.getY() + this.getBbHeight())));
            float f = ((float) (this.getTarget().getY() - this.getY()));
            float f2 = this.disV2(this.getTarget());
            return f2 <= 2.5 && f > 0f;
        }
        return false;
    }

    // 移动
    protected void WALK(Entity TargetEntity) {
        this.entityData.set(TICK, 25);
        this.entityData.set(ANIMATION_CD, 20);
        this.animationStart(WALK_TF);
        this.getNavigation().moveTo(TargetEntity, getAttributeValue(Attributes.MOVEMENT_SPEED));
    }

    // 待机判断
    public void isIdle(EntityDataAccessor<Boolean> animationName, EntityDataAccessor<Integer> attack_CD) {
        if (this.entityData.get(attack_CD) <= 1) {
            this.setDeltaMovement(0, -1, 0);
            this.getNavigation().stop();
            this.animationStart(animationName);
        } else {
            this.entityData.set(animationName, false);
        }
    }

    public void OnFireTF() {
        this.entityData.set(TICK, 10);
        this.entityData.set(ANIMATION_CD, 15);
        this.animationStart(ON_FIRE_TF);
        float random = this.getRandom().nextInt(-10,10);
        double x = this.getX() + random;
        double y = this.getY() + random;
        double z = this.getZ() + random;
        this.getNavigation().moveTo(x, y, z, getAttributeValue(Attributes.MOVEMENT_SPEED) * 1.4f);
//        this.getNavigation().moveTo()
    }

    // 技能计时器
    public void attackTickCount() {
        if (this.A01Hit > 0) {
            this.A01Hit--;
        }

        if (this.A02Hit > 0) {
            this.A02Hit--;
        }

        if (this.B01Hit > 0) {
            this.B01Hit--;
        }

        if (this.B01Cd > 0) {
            this.B01Cd--;
        }

        if (this.C01Hit > 0) {
            this.C01Hit--;
        }

        if (this.C01Cd > 0) {
            this.C01Cd--;
        }

        if (this.entityData.get(ANIMATION_CD) > 0) {
            this.entityData.set(ANIMATION_CD, entityData.get(ANIMATION_CD) - 1);
        }

        if (this.entityData.get(TICK) > 0) {
            this.entityData.set(TICK, entityData.get(TICK) - 1);
        }
        this.attackA01(2.5f, 2.5f);
        this.attackA02(2.5f, 2.1f);
        this.attackC01(0.7f, 2.1f);
        this.attackB01();
    }


    // 攻击看向
    public void lookTarget(Entity targetEntity) {
        if (!this.level().isClientSide()) {
            // 计算目标方向角度
            double dx = targetEntity.getX() - this.getX();
            double dz = targetEntity.getZ() - this.getZ();
            float targetYRot = (float) Math.toDegrees(Math.atan2(dz, dx)) - 90.0F;
            entityData.set(f1, Mth.rotLerp(0.15F, this.yRotO, targetYRot));
            entityData.set(f2, Mth.rotLerp(0.15F, this.yBodyRotO, targetYRot));
//            entityData.set(f3,targetEntity.getId());
        }
    }

    public void attackA01(float attackDis, float power) {
        float attackDamage = (((float) this.getAttributeValue(Attributes.ATTACK_DAMAGE) * Math.max(power, 1)));
        if (this.A01Hit == Math.abs(16)
                && this.getTarget() != null
                && this.isAlive()) {
            this.playSound(SoundEvents.SLIME_JUMP, 1.0F, 1.0F);
            this.setDeltaMovement(this.getLookAngle().x * 0.5, this.getDeltaMovement().y, this.getLookAngle().z * 0.5);
        }
        if (this.A01Hit == Math.abs(15)
                && this.getTarget() != null
                && this.isAlive()
                && this.disV3() <= attackDis) {
            this.playSound(SoundEvents.GENERIC_HURT, 1.0F, 1.0F);
            this.getTarget().hurt(this.damageSources().mobAttack(this), attackDamage);
            this.getTarget().setDeltaMovement(this.getLookAngle().x * 0.3, 0.3, this.getLookAngle().z * 0.3);
        }
    }

    public void attackA02(float attackDis, float power) {
        float attackDamage = (((float) this.getAttributeValue(Attributes.ATTACK_DAMAGE) * Math.max(power, 1)));
        if (this.A02Hit == Math.abs(17)
                && this.getTarget() != null
                && this.isAlive()) {
            this.setDeltaMovement(this.getLookAngle().x * 0.6, this.getDeltaMovement().y, this.getLookAngle().z * 0.6);
        }
        if (this.A02Hit == Math.abs(14)
                && this.getTarget() != null
                && this.isAlive()
                && this.disV3() <= attackDis) {
            this.playSound(SoundEvents.GENERIC_HURT, 1.0F, 1.0F);
            this.getTarget().hurt(this.damageSources().mobAttack(this), attackDamage);
            this.getTarget().setDeltaMovement(this.getLookAngle().x * 0.3, 0.3, this.getLookAngle().z * 0.3);
        }
    }

    public boolean B01TexTF() {
        return this.entityData.get(B01_TEX_TF);
    }

    public void attackB01() {

        if (this.B01Hit <= Math.abs(23) && this.B01Hit >= Math.abs(15)) {
            this.entityData.set(B01_TEX_TF, true);
        }
        if (this.B01Hit <= Math.abs(14) && this.B01Hit >= Math.abs(6)
                && this.isAlive()) {
            this.entityData.set(B01_TEX_TF, false);
            this.playSound(SoundEvents.ARROW_SHOOT, 1.0F, 4.0F);
            for (int i = 0; i < 3; i++) {
                PumpkinSeedEntity pumpkinSeedEntity = new PumpkinSeedEntity(ModEntitys.PUMPKIN_SEED.get(), this.level());
                pumpkinSeedEntity.setOwner(this);
                pumpkinSeedEntity.setPower(20);
                pumpkinSeedEntity.setPos(this.getX(), this.getEyeY() - 0.55f, this.getZ());
                pumpkinSeedEntity.shootFromRotation(this, this.getXRot() - 12F, this.yBodyRot, 0.0F, 1.1F, 12F);
                this.level().addFreshEntity(pumpkinSeedEntity);
            }
        }
    }

    public void attackC01(float attackDis, float power) {
        float attackDamage = (((float) this.getAttributeValue(Attributes.ATTACK_DAMAGE) * Math.max(power, 1)));
        if (this.C01Hit == Math.abs(26)
                && this.getTarget() != null
                && this.isAlive()) {
            this.setDeltaMovement(this.getLookAngle().x * 1.8f, this.getDeltaMovement().y + 0.35f, this.getLookAngle().z * 1.8f);
        }
        if (this.C01Hit < Math.abs(25)
                && this.C01Hit > Math.abs(17)
                && this.getTarget() != null
                && this.isAlive()
                && this.disV3() <= attackDis) {
            this.playSound(SoundEvents.GENERIC_HURT, 1.0F, 1.0F);
            this.getTarget().hurt(this.damageSources().mobAttack(this), attackDamage);
            this.getTarget().setDeltaMovement(this.getLookAngle().x * 0, 0.5, this.getLookAngle().z * 0);
        }
    }

    public void A01() {
        this.A01Hit = 30;
        this.entityData.set(TICK, 35);
        this.entityData.set(ANIMATION_CD, 30);
        this.setDeltaMovement(0, -1, 0);
//        this.LookTarget(this.getTarget());
        this.animationStart(A01_TF);

    }

    public void A02() {
        this.A02Hit = 30;
        this.entityData.set(TICK, 35);
        this.entityData.set(ANIMATION_CD, 30);
        this.setDeltaMovement(0, -1, 0);
//        this.LookTarget(this.getTarget());
        this.animationStart(A02_TF);
    }

    public void B01() {
        this.B01Hit = 30;
        this.C01Cd = 100;
        this.entityData.set(TICK, 35);
        this.entityData.set(ANIMATION_CD, 30);
        this.setDeltaMovement(0, -1, 0);
//        this.LookTarget(this.getTarget());
        this.animationStart(B01_TF);
    }

    public void C01() {
        this.C01Hit = 35;
        this.C01Cd = 200;
        this.entityData.set(TICK, 40);
        this.entityData.set(ANIMATION_CD, 35);
        this.setDeltaMovement(0, -1, 0);
//        this.LookTarget(this.getTarget());
        this.animationStart(C01_TF);
    }


    // 攻击逻辑选择
    public void mode() {
        if (this.isOnFire()) {
            if (this.entityData.get(ANIMATION_CD) <= 6 ){
                this.entityData.set(ANIMATION_CD, 15);
                this.animationStart(ON_FIRE_TF);
                ModEntityFunc.fireWalk(this);
            }
        }
        else {
            if (this.getTarget() != null && this.entityData.get(TICK) <= 0 && this.entityData.get(ANIMATION_CD) <= 0) {

                if (this.getTarget() != null && this.disV3() <= 2.5f) {
                    if (random.nextBoolean()) {
                        this.A01();
                    } else {
                        this.A02();
                    }
//            } else if (this.getTarget() != null && this.disV3(this.getTarget()) > 2.5f && this.disV3(this.getTarget()) <= 5.5f) {
                } else if (this.getTarget() != null && this.disV3() > 2.5f && this.disV3() <= 8f) {
                    if (this.C01Cd <= 0) {
                        if (random.nextBoolean()) {
                            this.C01();
//                        this.B01();
                        } else {
                            this.B01();
                        }
                    } else {
                        this.WALK(this.getTarget());
                    }
                } else {
                    this.WALK(this.getTarget());
                }
            }

        }
    }
/////////////////////////////////////////////////---------------------------触底线----------------------------------////////////////////////////////////////
}

