/*
 * Copyright (c) 2026 盐灯水母
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/.
 */

package com.remains_cave.entity;

import net.minecraft.network.syncher.EntityDataAccessor;
import net.minecraft.network.syncher.EntityDataSerializers;
import net.minecraft.network.syncher.SynchedEntityData;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.monster.Monster;
import net.minecraft.world.level.Level;
import net.minecraft.world.phys.Vec3;
import org.jetbrains.annotations.NotNull;
import software.bernie.geckolib.animatable.GeoEntity;
import software.bernie.geckolib.animatable.instance.AnimatableInstanceCache;
import software.bernie.geckolib.animation.*;
import software.bernie.geckolib.util.GeckoLibUtil;

public abstract class AbstractSkeletonEntity extends Monster implements GeoEntity {
    private final AnimatableInstanceCache cache = GeckoLibUtil.createInstanceCache(this);
    protected static final RawAnimation SUMMON_ANIM = RawAnimation.begin().thenPlay("summon");

    private static final EntityDataAccessor<Boolean> DATA_IS_SUMMONING =
            SynchedEntityData.defineId(AbstractSkeletonEntity.class, EntityDataSerializers.BOOLEAN);
    protected int summonAnimationTimer = 0;          // 服务端计时器，单位 tick
    private boolean summonAnimationStarted = false;  // 客户端避免重复触发

    public AbstractSkeletonEntity(EntityType<? extends Monster> type, Level level) {
        super(type, level);
    }

    @Override
    protected void defineSynchedData(SynchedEntityData.@NotNull Builder builder) {
        super.defineSynchedData(builder);
        builder.define(DATA_IS_SUMMONING, false);
    }

    /**
     * 开始召唤动画（服务端调用）
     */
    public void startSummonAnimation() {
        if (level().isClientSide) return;
        summonAnimationTimer = 40;          // 2 秒
        this.entityData.set(DATA_IS_SUMMONING, true);
        // 立即清除 AI 状态，防止任何行动
        this.setTarget(null);
        this.getNavigation().stop();
        this.getMoveControl().setWantedPosition(this.getX(), this.getY(), this.getZ(), 0.0);
        this.setDeltaMovement(Vec3.ZERO);
    }

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

        // ===== 服务端逻辑 =====
        if (!level().isClientSide) {
            // 1. 召唤动画计时
            if (summonAnimationTimer > 0) {
                summonAnimationTimer--;
                if (summonAnimationTimer <= 0) {
                    // 动画结束，恢复 AI
                    this.entityData.set(DATA_IS_SUMMONING, false);
                }
            }

            // 2. 动画期间强制静止
            if (isSummoning()) {
                this.setTarget(null);
                this.getNavigation().stop();
                this.getMoveControl().setWantedPosition(this.getX(), this.getY(), this.getZ(), 0.0);
                this.setDeltaMovement(Vec3.ZERO);
            }
        }

        // ===== 客户端逻辑（动画触发） =====
        if (level().isClientSide) {
            boolean summoningFlag = this.entityData.get(DATA_IS_SUMMONING);
            if (summoningFlag && !summonAnimationStarted) {
                // 确保动画只触发一次，避免重复播放
                this.triggerAnim("controller", "summon");
                summonAnimationStarted = true;
            } else if (!summoningFlag && summonAnimationStarted) {
                summonAnimationStarted = false;
            }
        }
    }

    @Override
    public boolean hurt(@NotNull DamageSource source, float amount) {
        // 动画期间 80% 伤害减免
        if (isSummoning()) {
            amount *= 0.2f;
        }
        return super.hurt(source, amount);
    }

    @Override
    public void knockback(double strength, double x, double z) {
        if (!isSummoning()) {
            super.knockback(strength, x, z);
        }
        // 动画期间直接忽略击退
    }

    /**
     * 判断当前是否处于召唤动画中
     */
    public boolean isSummoning() {
        if (level().isClientSide) {
            return this.entityData.get(DATA_IS_SUMMONING);
        } else {
            return summonAnimationTimer > 0;
        }
    }

    // ---------- 抽象方法，由子类实现各自动画 ----------
    @Override
    public abstract void registerControllers(AnimatableManager.ControllerRegistrar controllers);

    @Override
    public AnimatableInstanceCache getAnimatableInstanceCache() {
        return cache;
    }

    // ---------- 重写部分属性，确保 AI 在动画期间被阻断 ----------
    @Override
    public void setTarget(LivingEntity target) {
        if (!isSummoning()) {
            super.setTarget(target);
        } else {
            // 动画期间不允许设置目标
            super.setTarget(null);
        }
    }
}