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

import com.google.gson.JsonObject;
import com.tiedup.remake.core.TiedUpMod;
import com.tiedup.remake.util.GagMaterial;
import java.util.List;
import net.minecraft.ChatFormatting;
import net.minecraft.network.chat.Component;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.TooltipFlag;
import net.minecraft.world.level.Level;
import org.jetbrains.annotations.Nullable;

/**
 * Component: gagging behavior for data-driven items.
 *
 * <p>Config-driven: {@code "gagging": {"material": "ball"}} delegates to
 * {@link GagMaterial} for comprehension/range from ModConfig at runtime.</p>
 *
 * <p>Override: {@code "gagging": {"comprehension": 0.15, "range": 8.0}} uses
 * explicit values that take priority over the material lookup.</p>
 */
public class GaggingComponent implements IItemComponent {

    private final @Nullable String material;
    private final @Nullable GagMaterial cachedMaterial;
    private final double comprehensionOverride;
    private final double rangeOverride;

    private GaggingComponent(@Nullable String material, @Nullable GagMaterial cachedMaterial,
                             double comprehensionOverride, double rangeOverride) {
        this.material = material;
        this.cachedMaterial = cachedMaterial;
        this.comprehensionOverride = comprehensionOverride;
        this.rangeOverride = rangeOverride;
    }

    public static IItemComponent fromJson(JsonObject config) {
        String material = null;
        double comprehension = -1;
        double range = -1;
        if (config != null) {
            if (config.has("material")) {
                material = config.get("material").getAsString();
            }
            if (config.has("comprehension")) {
                comprehension = Math.max(0.0, Math.min(1.0, config.get("comprehension").getAsDouble()));
            }
            if (config.has("range")) {
                range = Math.max(0.0, config.get("range").getAsDouble());
            }
        }
        // Resolve and cache GagMaterial at load time to avoid valueOf() on every chat message
        GagMaterial resolved = null;
        if (material != null) {
            try {
                resolved = GagMaterial.valueOf(material.toUpperCase());
            } catch (IllegalArgumentException e) {
                TiedUpMod.LOGGER.warn("[GaggingComponent] Unknown gag material '{}' — using defaults", material);
            }
        }
        return new GaggingComponent(material, resolved, comprehension, range);
    }

    /** How much of the gagged speech is comprehensible (0.0 = nothing, 1.0 = full). */
    public double getComprehension() {
        if (comprehensionOverride >= 0) return comprehensionOverride;
        GagMaterial gag = getMaterial();
        if (gag != null) return gag.getComprehension();
        return 0.2;
    }

    /** Maximum range in blocks where muffled speech can be heard. */
    public double getRange() {
        if (rangeOverride >= 0) return rangeOverride;
        GagMaterial gag = getMaterial();
        if (gag != null) return gag.getTalkRange();
        return 10.0;
    }

    /** The gag material enum, or null if not configured or invalid. Cached at load time. */
    public @Nullable GagMaterial getMaterial() {
        return cachedMaterial;
    }

    /** The raw material string from JSON, or null. */
    public @Nullable String getMaterialName() {
        return material;
    }

    @Override
    public void appendTooltip(ItemStack stack, @Nullable Level level, List<Component> tooltip, TooltipFlag flag) {
        if (material != null) {
            tooltip.add(Component.translatable("item.tiedup.tooltip.gag_material", material)
                .withStyle(ChatFormatting.RED));
        } else {
            tooltip.add(Component.translatable("item.tiedup.tooltip.gagging").withStyle(ChatFormatting.RED));
        }
    }
}
