/*
 * 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.item.custom;

import com.remains_cave.entity.client.TombBowRenderer;
import com.remains_cave.item.ModItems;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.BlockEntityWithoutLevelRenderer;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.BowItem;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level;
import net.neoforged.neoforge.client.extensions.common.IClientItemExtensions;
import org.jetbrains.annotations.NotNull;
import software.bernie.geckolib.animatable.GeoItem;
import software.bernie.geckolib.animatable.instance.AnimatableInstanceCache;
import software.bernie.geckolib.animation.*;
import software.bernie.geckolib.util.GeckoLibUtil;
import software.bernie.geckolib.constant.DataTickets;

import java.util.WeakHashMap;
import java.util.concurrent.ConcurrentHashMap;
import java.util.Map;
import java.util.function.Consumer;
import net.minecraft.world.item.Item.Properties;
import net.minecraft.world.item.Item;

public class TombBowItem extends BowItem implements GeoItem {
    private final AnimatableInstanceCache cache = GeckoLibUtil.createInstanceCache(this);

    private static final Map<Long, PullState> PULL_STATES = new WeakHashMap<>();

    private static class PullState {
        boolean wasPulling = false;
        boolean shootTriggered = false;
    }

    public TombBowItem(Properties properties) {
        super(properties);
    }

    @Override
    public void registerControllers(AnimatableManager.ControllerRegistrar controllers) {
        controllers.add(new AnimationController<>(this, "pull_controller", 0, state -> {
            ItemStack stack = state.getData(DataTickets.ITEMSTACK);
            if (stack == null || stack.isEmpty()) return PlayState.STOP;

            long id = GeoItem.getId(stack);
            if (id == Long.MAX_VALUE) return PlayState.STOP; // 无ID不播放动画

            PullState pullState = PULL_STATES.computeIfAbsent(id, k -> new PullState());

            Player player = Minecraft.getInstance().player;
            if (player == null) return PlayState.STOP;

            ItemStack useItem = player.getUseItem();
            boolean isPulling = player.isUsingItem() && !useItem.isEmpty() && GeoItem.getId(useItem) == id;
            // 或者使用ID比较：
            // boolean isPulling = player.isUsingItem() && !useItem.isEmpty()
            //         && GeoItem.getId(useItem) == id;

            var controller = state.getController();

            if (pullState.wasPulling && !isPulling) {
                pullState.shootTriggered = true;
            }
            pullState.wasPulling = isPulling;

            if (isPulling) {
                var currentAnim = controller.getCurrentAnimation();
                if (currentAnim == null || !currentAnim.animation().name().equals("animation.tomb_bow.pull")) {
                    controller.setAnimation(RawAnimation.begin().then("animation.tomb_bow.pull", Animation.LoopType.HOLD_ON_LAST_FRAME));
                }
                pullState.shootTriggered = false;
                return PlayState.CONTINUE;
            }

            if (pullState.shootTriggered) {
                var currentAnim = controller.getCurrentAnimation();
                if (currentAnim == null || !currentAnim.animation().name().equals("animation.tomb_bow.shoot")) {
                    controller.setAnimation(RawAnimation.begin().then("animation.tomb_bow.shoot", Animation.LoopType.PLAY_ONCE));
                } else {
                    if (controller.getAnimationState() == AnimationController.State.STOPPED) {
                        pullState.shootTriggered = false;
                        return PlayState.STOP;
                    }
                }
                return PlayState.CONTINUE;
            }

            return PlayState.STOP;
        }));
    }

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

    @Override
    public boolean isPerspectiveAware() {
        return true;
    }

    @Override
    @SuppressWarnings("removal")
    public void initializeClient(Consumer<IClientItemExtensions> consumer) {
        consumer.accept(new IClientItemExtensions() {
            private TombBowRenderer renderer;

            @Override
            public @NotNull BlockEntityWithoutLevelRenderer getCustomRenderer() {
                if (renderer == null) {
                    renderer = new TombBowRenderer();
                }
                return renderer;
            }
        });
    }
    @Override
    public boolean isValidRepairItem(@NotNull ItemStack toRepair, ItemStack repair) {
        return repair.is(ModItems.CRIMSON_CRYSTAL.get());
    }

    @Override
    public boolean isRepairable(@NotNull ItemStack stack) {
        return true;
    }
    @Override
    public void inventoryTick(@NotNull ItemStack stack, Level level, net.minecraft.world.entity.@NotNull Entity entity, int slotId, boolean isSelected) {
        if (!level.isClientSide && level instanceof ServerLevel serverLevel) {
            GeoItem.getOrAssignId(stack, serverLevel);
        }
        super.inventoryTick(stack, level, entity, slotId, isSelected);
    }
}