package com.tiedup.remake.client.events;

import com.tiedup.remake.client.MuffledSoundInstance;
import com.tiedup.remake.core.ModConfig;
import com.tiedup.remake.core.TiedUpMod;
import com.tiedup.remake.state.PlayerBindState;
import net.minecraft.client.Minecraft;
import net.minecraft.client.player.LocalPlayer;
import net.minecraft.client.resources.sounds.SoundInstance;
import net.minecraft.sounds.SoundSource;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.client.event.sound.PlaySoundEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;

/**
 * Client-side sound handler for earplugs effect.
 *
 * When the player has earplugs equipped, all sounds are muffled
 * (volume reduced to simulate hearing impairment).
 *
 * Based on Forge's PlaySoundEvent to intercept and modify sounds.
 */
@OnlyIn(Dist.CLIENT)
@Mod.EventBusSubscriber(
    modid = TiedUpMod.MOD_ID,
    bus = Mod.EventBusSubscriber.Bus.FORGE,
    value = Dist.CLIENT
)
public class EarplugSoundHandler {

    /** Pitch modifier to make sounds more muffled (much lower for "underwater" effect) */
    private static final float MUFFLED_PITCH_MODIFIER = 0.6f;

    /** Categories to always let through at normal volume (important UI feedback) */
    private static final SoundSource[] UNAFFECTED_CATEGORIES = {
        SoundSource.MASTER, // Master volume controls
        SoundSource.MUSIC, // Music is internal, not muffled by earplugs
    };

    /**
     * Intercept sound events and muffle them if player has earplugs.
     */
    @SubscribeEvent
    public static void onPlaySound(PlaySoundEvent event) {
        // Get the sound being played
        SoundInstance sound = event.getSound();
        if (sound == null) {
            return;
        }

        // Check if player has earplugs
        Minecraft mc = Minecraft.getInstance();
        if (mc == null) {
            return;
        }
        LocalPlayer player = mc.player;
        if (player == null) {
            return;
        }

        PlayerBindState state = PlayerBindState.getInstance(player);
        if (state == null || !state.hasEarplugs()) {
            return;
        }

        // Check if this sound category should be affected
        SoundSource source = sound.getSource();
        for (SoundSource unaffected : UNAFFECTED_CATEGORIES) {
            if (source == unaffected) {
                return; // Don't muffle this category
            }
        }

        // Don't wrap already-wrapped sounds (prevent infinite recursion)
        if (sound instanceof MuffledSoundInstance) {
            return;
        }

        // Wrap the sound with our muffling wrapper
        // The wrapper delegates to the original but modifies getVolume()/getPitch()
        SoundInstance muffledSound = new MuffledSoundInstance(
            sound,
            ModConfig.CLIENT.earplugVolumeMultiplier.get().floatValue(),
            MUFFLED_PITCH_MODIFIER
        );

        event.setSound(muffledSound);
    }
}
