package com.tiedup.remake.v2.bondage.component;

import java.util.Collections;
import java.util.EnumMap;
import java.util.List;
import java.util.Map;
import net.minecraft.network.chat.Component;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.TooltipFlag;
import net.minecraft.world.level.Level;
import org.jetbrains.annotations.Nullable;

public final class ComponentHolder {

    public static final ComponentHolder EMPTY = new ComponentHolder(Map.of());

    private final Map<ComponentType, IItemComponent> components;

    public ComponentHolder(Map<ComponentType, IItemComponent> components) {
        this.components = components.isEmpty()
            ? Map.of()
            : Collections.unmodifiableMap(new EnumMap<>(components));
    }

    @Nullable
    public IItemComponent get(ComponentType type) {
        return components.get(type);
    }

    @Nullable
    @SuppressWarnings("unchecked")
    public <T extends IItemComponent> T get(
        ComponentType type,
        Class<T> clazz
    ) {
        IItemComponent component = components.get(type);
        if (clazz.isInstance(component)) return (T) component;
        return null;
    }

    public boolean has(ComponentType type) {
        return components.containsKey(type);
    }

    public void onEquipped(ItemStack stack, LivingEntity entity) {
        for (IItemComponent c : components.values()) {
            c.onEquipped(stack, entity);
        }
    }

    public void onUnequipped(ItemStack stack, LivingEntity entity) {
        for (IItemComponent c : components.values()) {
            c.onUnequipped(stack, entity);
        }
    }

    public boolean blocksUnequip(ItemStack stack, LivingEntity entity) {
        for (IItemComponent c : components.values()) {
            if (c.blocksUnequip(stack, entity)) return true;
        }
        return false;
    }

    public void appendTooltip(ItemStack stack, @Nullable Level level, List<Component> tooltip, TooltipFlag flag) {
        for (IItemComponent c : components.values()) {
            c.appendTooltip(stack, level, tooltip, flag);
        }
    }

    public boolean isEmpty() {
        return components.isEmpty();
    }
}
