package de.winniepat.citrus.cosmetics.halo;

import de.winniepat.citrus.cosmetics.CosmeticSyncManager;
import net.minecraft.entity.player.PlayerEntity;
import software.bernie.geckolib.animatable.GeoAnimatable;
import software.bernie.geckolib.animatable.instance.AnimatableInstanceCache;
import software.bernie.geckolib.animation.*;
import software.bernie.geckolib.util.GeckoLibUtil;

public class CosmeticHalo implements GeoAnimatable {
    private final AnimatableInstanceCache cache = GeckoLibUtil.createInstanceCache(this);
    private final PlayerEntity player;

    public CosmeticHalo(PlayerEntity player) {
        this.player = player;
    }

    public PlayerEntity getPlayer() {
        return this.player;
    }

    public HaloType getHaloType() {
        CosmeticSyncManager.SyncedCosmeticData syncedData =
                CosmeticSyncManager.getSyncedCosmetics(
                        player.getUuid(),
                        player.getName().getString()
                );

        if (syncedData != null && CosmeticSyncManager.hasInitialSyncCompleted()) {
            return HaloType.fromId(syncedData.haloType);
        }

        String haloId = de.winniepat.citrus.cosmetics.ClientCosmeticManager.getActiveHalo(player.getUuid());
        return HaloType.fromId(haloId);
    }

    public boolean shouldRender() {
        HaloType type = getHaloType();
        if (type == HaloType.NONE) {
            return false;
        }

        CosmeticSyncManager.SyncedCosmeticData syncedData =
                CosmeticSyncManager.getSyncedCosmetics(
                        player.getUuid(),
                        player.getName().getString()
                );

        if (syncedData != null && CosmeticSyncManager.hasInitialSyncCompleted()) {
            return syncedData.haloVisible && !player.isInvisible();
        }

        return de.winniepat.citrus.cosmetics.ClientCosmeticManager.isHaloVisible(player.getUuid()) && !player.isInvisible();
    }

    @Override
    public void registerControllers(AnimatableManager.ControllerRegistrar controllers) {
        controllers.add(new AnimationController<>(this, "controller", 0, state -> {
            HaloType type = state.getAnimatable().getHaloType();
            if (type == HaloType.NONE) {
                return null;
            }

            return state.setAndContinue(RawAnimation.begin().thenLoop("animation.halo.float"));
        }));
    }

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

    @Override
    public double getTick(Object object) {
        return this.player.age;
    }
}