/*
 * 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.block.entity;

import com.remains_cave.block.ModBlocks;
import com.remains_cave.block.SkeletonKingSummonBlock;
import com.remains_cave.dungeon.room.RoomManager;
import com.remains_cave.entity.ModEntities;
import com.remains_cave.entity.SkeletonKingEntity;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.core.HolderLookup;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
import software.bernie.geckolib.animatable.GeoBlockEntity;
import software.bernie.geckolib.animatable.instance.AnimatableInstanceCache;
import software.bernie.geckolib.animation.AnimatableManager;
import software.bernie.geckolib.animation.AnimationController;
import software.bernie.geckolib.animation.RawAnimation;
import software.bernie.geckolib.animation.Animation;
import software.bernie.geckolib.util.GeckoLibUtil;
import org.jetbrains.annotations.NotNull;

import java.util.List;

public class SkeletonKingSummonBlockEntity extends BlockEntity implements GeoBlockEntity {
    private static final RawAnimation STATIC_ANIM = RawAnimation.begin().thenLoop("static");
    private static final RawAnimation REVIVE_ANIM = RawAnimation.begin()
            .then("revive", Animation.LoopType.PLAY_ONCE);

    private static final int REVIVE_ANIMATION_TICKS = 70; // 3.5秒 * 20 ticks/秒
    private boolean revived = false;
    private int reviveTimer = 0;
    private boolean animationTriggered = false;

    private String roomId = "";
    public void setRoomId(String roomId) { this.roomId = roomId; }
    public String getRoomId() { return roomId; }

    private final AnimatableInstanceCache cache = GeckoLibUtil.createInstanceCache(this);

    public SkeletonKingSummonBlockEntity(BlockPos pos, BlockState state) {
        super(ModBlocks.SKELETON_KING_SUMMON_BLOCK_ENTITY.get(), pos, state);
    }

    // ========== 服务端逻辑 ==========
    public void serverTick() {
        if (level == null || level.isClientSide) return;

        if (revived) {
            if (reviveTimer > 0) {
                reviveTimer--;
                if (reviveTimer == 0) {
                    destroyAndSpawn();
                }
            }
            return;
        }

        // 检测周围 10x10x10 内是否存在生存或冒险模式的玩家
// 在 serverTick 方法中替换玩家检测部分
        Direction facing = getBlockState().getValue(SkeletonKingSummonBlock.FACING);
        Vec3 blockCenter = Vec3.atCenterOf(worldPosition);

// 定义局部坐标轴
        Vec3 forward = new Vec3(facing.getStepX(), 0, facing.getStepZ()).normalize();
        Vec3 left = new Vec3(facing.getStepZ(), 0, -facing.getStepX()).normalize(); // 左方向

// 扩大 AABB 加速过滤（比实际区域稍大）
        AABB detectionBox = new AABB(worldPosition).inflate(13, 6, 13); // 约前后13，上下6，左右13
        List<Player> players = level.getEntitiesOfClass(Player.class, detectionBox);
        boolean hasValidPlayer = false;

        for (Player player : players) {
            if (player.isCreative() || player.isSpectator()) continue;

            Vec3 rel = player.position().subtract(blockCenter);
            double forwardDist = rel.dot(forward);   // 前后方向（正为前）
            double leftDist = rel.dot(left);         // 左右方向
            double verticalDist = rel.y;             // 垂直方向

            // 检查是否在矩形区域内
            if (forwardDist >= -1.0 && forwardDist <= 12.0 &&   // 后方1格 ~ 前方12格
                    Math.abs(leftDist) <= 5.0 &&                    // 左右各5格
                    verticalDist >= -4.0 && verticalDist <= 5.0) {  // 下方3格 ~ 上方5格
                hasValidPlayer = true;
                break;
            }
        }

        if (hasValidPlayer) {
            revived = true;
            reviveTimer = REVIVE_ANIMATION_TICKS;
            syncToClient();
        }
    }

    private void destroyAndSpawn() {
        if (level == null || level.isClientSide) return;
        Direction facing = getBlockState().getValue(SkeletonKingSummonBlock.FACING);
        SkeletonKingEntity king = new SkeletonKingEntity(ModEntities.SKELETON_KING.get(), level);
        king.setPos(worldPosition.getX() + 0.5, worldPosition.getY(), worldPosition.getZ() + 0.5);
        // 设置实体的偏航角
        king.setYRot(facing.toYRot());
        // 同步头部旋转，避免转头动画突兀
        king.yHeadRot = king.getYRot();
        king.setSummonBlockInfo(worldPosition, facing);
        level.addFreshEntity(king);
        level.setBlock(worldPosition, Blocks.AIR.defaultBlockState(), Block.UPDATE_ALL);
        // ... 现有代码创建 king ...
        if (!roomId.isEmpty()) {
            king.setRoomId(roomId);
            // 通知房间管理器 Boss 激活
            if (level instanceof ServerLevel serverLevel) {
                RoomManager.get(level).activateBoss(roomId, serverLevel);
            }
        }
    }

    private void syncToClient() {
        if (level != null && !level.isClientSide) {
            setChanged(); // 标记数据已修改
            // 发送方块状态更新，使客户端重新请求 BlockEntity 数据
            level.sendBlockUpdated(worldPosition, getBlockState(), getBlockState(), Block.UPDATE_ALL);
            // 强制区块更新（NeoForge/Forge 特有）
            if (level instanceof ServerLevel serverLevel) {
                serverLevel.getChunkSource().blockChanged(worldPosition);
            }
        }
    }

    // ========== 客户端逻辑 ==========
// ========== 客户端逻辑 ==========
    public void clientTick() {
        if (level == null || !level.isClientSide) return;

        // 如果动画尚未触发且未处于已召唤状态，进行玩家检测
        if (!animationTriggered && !revived) {
            Direction facing = getBlockState().getValue(SkeletonKingSummonBlock.FACING);
            Vec3 blockCenter = Vec3.atCenterOf(worldPosition);

            // 定义局部坐标轴
            Vec3 forward = new Vec3(facing.getStepX(), 0, facing.getStepZ()).normalize();
            Vec3 left = new Vec3(facing.getStepZ(), 0, -facing.getStepX()).normalize();

            // 扩大 AABB 加速过滤（比实际区域稍大）
            AABB detectionBox = new AABB(worldPosition).inflate(13, 6, 13);
            List<Player> players = level.getEntitiesOfClass(Player.class, detectionBox);
            boolean hasValidPlayer = false;

            for (Player player : players) {
                if (player.isCreative() || player.isSpectator()) continue;

                Vec3 rel = player.position().subtract(blockCenter);
                double forwardDist = rel.dot(forward);   // 前后方向（正为前）
                double leftDist = rel.dot(left);         // 左右方向
                double verticalDist = rel.y;             // 垂直方向

                // 检查是否在矩形区域内（与服务端完全一致）
                if (forwardDist >= -1.0 && forwardDist <= 12.0 &&   // 后方1格 ~ 前方12格
                        Math.abs(leftDist) <= 5.0 &&                    // 左右各5格
                        verticalDist >= -4.0 && verticalDist <= 5.0) {  // 下方3格 ~ 上方5格
                    hasValidPlayer = true;
                    break;
                }
            }

            if (hasValidPlayer) {
                this.triggerAnim("summon_controller", "revive");
                animationTriggered = true;
                revived = true; // 避免重复检测
            }
        }
    }

    // ========== GeckoLib 动画注册 ==========
    @Override
    public void registerControllers(AnimatableManager.ControllerRegistrar controllers) {
        // 关键：添加 triggerableAnim 注册 revive 动画
        controllers.add(new AnimationController<>(this, "summon_controller", 0, state -> {
            return state.setAndContinue(STATIC_ANIM);
        }).triggerableAnim("revive", REVIVE_ANIM)); // 这里注册可触发的动画
    }

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

    // ========== 数据同步 ==========
    @Override
    protected void saveAdditional(@NotNull CompoundTag tag, HolderLookup.@NotNull Provider registries) {
        super.saveAdditional(tag, registries);
        tag.putBoolean("Revived", revived);
        tag.putInt("ReviveTimer", reviveTimer);

        tag.putString("RoomId", roomId);

    }

    @Override
    protected void loadAdditional(@NotNull CompoundTag tag, HolderLookup.@NotNull Provider registries) {
        super.loadAdditional(tag, registries);
        revived = tag.getBoolean("Revived");
        reviveTimer = tag.getInt("ReviveTimer");

        roomId = tag.getString("RoomId");
    }

    @Override
    public CompoundTag getUpdateTag(HolderLookup.Provider registries) {
        CompoundTag tag = super.getUpdateTag(registries);
        tag.putBoolean("Revived", revived);
        tag.putInt("ReviveTimer", reviveTimer);
        return tag;
    }

    @Override
    public void handleUpdateTag(CompoundTag tag, HolderLookup.Provider registries) {
        super.handleUpdateTag(tag, registries);
        revived = tag.getBoolean("Revived");
        reviveTimer = tag.getInt("ReviveTimer");
        if (level != null && level.isClientSide && revived && !animationTriggered) {
            net.minecraft.client.Minecraft.getInstance().execute(() -> {
                this.triggerAnim("summon_controller", "revive");
            });
            animationTriggered = true;
        }
    }
}