/*
 *  Copyright 2025-2026 R3944Realms
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

package top.r3944realms.eroticdungeongame.content.block.blockentity;

import net.minecraft.core.BlockPos;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.properties.WoodType;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import software.bernie.geckolib.animatable.GeoBlockEntity;
import software.bernie.geckolib.core.animatable.instance.AnimatableInstanceCache;
import software.bernie.geckolib.core.animation.AnimatableManager;
import software.bernie.geckolib.core.animation.AnimationController;
import software.bernie.geckolib.core.animation.RawAnimation;
import software.bernie.geckolib.util.GeckoLibUtil;
import top.r3944realms.eroticdungeongame.content.animation.EDGAnimation;
import top.r3944realms.eroticdungeongame.content.block.type.SpanishDonkeyBlock;
import top.r3944realms.eroticdungeongame.core.register.EDGBlockEntities;
import top.r3944realms.lib39.util.nbt.NBTReader;
import top.r3944realms.lib39.util.nbt.NBTWriter;

import java.util.UUID;

public class SpanishDonkeyBlockEntity extends BaseSeatBlockEntity implements GeoBlockEntity {
    private final AnimatableInstanceCache cache = GeckoLibUtil.createInstanceCache(this);
    public static final RawAnimation SHOCK_WOR_ANIM = RawAnimation.begin().thenPlay("donkey.shock_without_route");
    public static final RawAnimation SHOCK_WR_ANIM = RawAnimation.begin().thenPlay("donkey.shock_with_route");
    public static final RawAnimation R_ANIM = RawAnimation.begin().thenPlay("donkey.routed");
    public static final RawAnimation UR_ANIM = RawAnimation.begin().thenPlay("donkey.unrouted");
    public static final RawAnimation RI_ANIM = RawAnimation.begin().thenPlay("donkey.routing").thenPlayAndHold("donkey.routed");
    public static final RawAnimation URI_ANIM = RawAnimation.begin().thenPlay("donkey.unrouting").thenPlayAndHold("donkey.unrouted");

    private volatile boolean isShock = false;
    private volatile boolean isRoute = false;

    private volatile boolean shouldPlayRouting = false;
    private volatile boolean shouldPlayUnrouting = false;
    private volatile WoodType woodType;
    public SpanishDonkeyBlockEntity(BlockPos blockPos, BlockState blockState) {
        super(EDGBlockEntities.SPANISH_DONKEY_BLOCK_ENTITY.get(), blockPos, blockState);
    }
    @Contract(pure = true)
    public static void serverTick(Level pLevel, BlockPos pPos, BlockState pState, @NotNull SpanishDonkeyBlockEntity pBlockEntity) {
        if (pBlockEntity.shouldPlayRouting) {
            UUID boundPlayerUUID = pBlockEntity.getBoundPlayerUUID();
            if (boundPlayerUUID != null) {
                Player playerByUUID = pLevel.getPlayerByUUID(boundPlayerUUID);
                if (playerByUUID != null && !EDGAnimation.isPlayerAnimation(playerByUUID, EDGAnimation.SPANISH_DONKEY, 3)) {
                    EDGAnimation.SPANISH_DONKEY.play(playerByUUID, 3);
                }
            }
        } else if (pBlockEntity.shouldPlayUnrouting) {
            UUID boundPlayerUUID = pBlockEntity.getBoundPlayerUUID();
            if (boundPlayerUUID != null) {
                Player playerByUUID = pLevel.getPlayerByUUID(boundPlayerUUID);
                if (playerByUUID != null && !EDGAnimation.isPlayerAnimation(playerByUUID, EDGAnimation.SPANISH_DONKEY, 4)) {
                    EDGAnimation.SPANISH_DONKEY.play(playerByUUID, 4);
                }
            }
        }
    }
    public boolean isShock() {
        return isShock;
    }

    public void setShock(boolean shock) {
        isShock = shock;
    }
    public WoodType getWoodType() {
        if (woodType == null) {
            BlockState state = getBlockState();
            if (state.getBlock() instanceof SpanishDonkeyBlock block) {
                woodType = block.getWoodType();
            }
        }
        return woodType;
    }

    public synchronized void route() {
        shouldPlayRouting = true;
        shouldPlayUnrouting = false;
        isRoute = true; // 更新状态
    }

    public synchronized void unroute() {
        shouldPlayRouting = false;
        shouldPlayUnrouting = true;
        isRoute = false; // 更新状态
    }

    public synchronized void toggleRoute() {
        if (isRoute) {
            unroute();
        } else {
            route();
        }
    }

    public boolean isRoute() {
        return isRoute;
    }

    public void setRoute(boolean route) {
        isRoute = route;
    }

    public boolean isShouldPlayRouting() {
        return shouldPlayRouting;
    }

    public void setShouldPlayRouting(boolean shouldPlayRouting) {
        this.shouldPlayRouting = shouldPlayRouting;
    }

    public boolean isShouldPlayUnrouting() {
        return shouldPlayUnrouting;
    }

    public void setShouldPlayUnrouting(boolean shouldPlayUnrouting) {
        this.shouldPlayUnrouting = shouldPlayUnrouting;
    }

    @Override
    public void registerControllers(AnimatableManager.ControllerRegistrar controllerRegistrar) {
        controllerRegistrar.add(
                new AnimationController<>(this, "spanish_donkey", 0, state -> {
                    if (isShock) {
                        if (isRoute) return state.setAndContinue(SHOCK_WR_ANIM);
                        else return state.setAndContinue(SHOCK_WOR_ANIM);
                    } else {
                        if (shouldPlayRouting) {
                            shouldPlayRouting = false;
                            return state.setAndContinue(RI_ANIM);
                        }
                        if (shouldPlayUnrouting) {
                            shouldPlayUnrouting = false;
                            return state.setAndContinue(URI_ANIM);
                        }
                        if (state.isCurrentAnimationStage("donkey.routing")) {
                            return state.setAndContinue(RI_ANIM);
                        }

                        if (state.isCurrentAnimationStage("donkey.unrouting")) {
                            return state.setAndContinue(URI_ANIM);
                        }
                        return isRoute ? state.setAndContinue(R_ANIM) :
                        state.setAndContinue(UR_ANIM);
                    }
                })
        );
    }

    @Override
    public int getPlayerAnimationNumber() {
        return isRoute ? 2 : 1;
    }

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

    @Override
    public void saveAdditional(@NotNull CompoundTag compoundTag) {
        super.saveAdditional(compoundTag);
        NBTWriter.of(compoundTag)
                .booleanValue("shock", isShock)
                .booleanValue("isRoute", isRoute)
                .booleanValue("shouldPlayRouting", isShouldPlayRouting())
                .booleanValue("shouldPlayUnrouting", isShouldPlayUnrouting());
    }

    @Override
    public void load(@NotNull CompoundTag compoundTag) {
        super.load(compoundTag);
        NBTReader.of(compoundTag)
                .booleanValue("shock",this::setShock)
                .booleanValue("isRoute",this::setRoute)
                .booleanValue("shouldPlayRouting",this::setShouldPlayRouting)
                .booleanValue("shouldPlayUnrouting",this::setShouldPlayUnrouting);
    }


}
