package com.tiedup.remake.mixin;

import com.tiedup.remake.compat.mca.MCACompat;
import com.tiedup.remake.core.TiedUpMod;
import com.tiedup.remake.dialogue.GagTalkManager;
import com.tiedup.remake.state.IBondageState;
import com.tiedup.remake.v2.BodyRegionV2;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.MutableComponent;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.item.ItemStack;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Pseudo;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;

/**
 * Mixin for MCA's VillagerEntityMCA to handle gagged speech.
 *
 * <p>This mixin provides method implementations that override the default methods
 * from MCA's Messenger interface. When the villager is gagged:
 * <ul>
 *   <li>isSpeechImpaired() returns true (blocks TTS)</li>
 *   <li>playSpeechEffect() does nothing (silence)</li>
 *   <li>transformMessage() applies gagtalk transformation</li>
 *   <li>playWelcomeSound() is cancelled (no greeting)</li>
 *   <li>playSurprisedSound() is cancelled (no surprise sound)</li>
 * </ul>
 *
 * <p>Uses @Pseudo for soft dependency - only applies if MCA is present.
 */
@Pseudo
@Mixin(targets = "forge.net.mca.entity.VillagerEntityMCA", remap = false)
public abstract class MixinMCAMessenger {

    /**
     * Override isSpeechImpaired to return true when gagged.
     *
     * <p>This blocks TTS voice generation in MCA's SpeechManager.
     * When the villager is not gagged, returns false (normal speech).
     *
     * @return true if gagged, false otherwise
     */
    public boolean isSpeechImpaired() {
        try {
            LivingEntity entity = (LivingEntity) (Object) this;
            IBondageState state = MCACompat.getKidnappedState(entity);

            if (state != null && state.isGagged()) {
                return true;
            }
        } catch (Exception e) {
            TiedUpMod.LOGGER.debug(
                "[MCA] isSpeechImpaired check failed: {}",
                e.getMessage()
            );
        }

        return false;
    }

    /**
     * Override playSpeechEffect to produce complete silence when gagged.
     *
     * <p>When the villager is gagged, this method does nothing (no sound).
     * When not gagged, delegates to default behavior.
     */
    public void playSpeechEffect() {
        try {
            LivingEntity entity = (LivingEntity) (Object) this;
            IBondageState state = MCACompat.getKidnappedState(entity);

            if (state != null && state.isGagged()) {
                TiedUpMod.LOGGER.debug(
                    "[MCA] playSpeechEffect cancelled for gagged villager"
                );
                return;
            }
        } catch (Exception e) {
            TiedUpMod.LOGGER.debug(
                "[MCA] playSpeechEffect check failed: {}",
                e.getMessage()
            );
        }
    }

    /**
     * Override transformMessage to apply gagtalk when gagged.
     *
     * <p>When the villager is gagged, transforms the message using
     * TiedUp's GagTalkManager. When not gagged, returns the original
     * message unchanged.
     *
     * @param message The original message
     * @return The gagged message if gagged, original otherwise
     */
    public MutableComponent transformMessage(MutableComponent message) {
        try {
            LivingEntity entity = (LivingEntity) (Object) this;
            IBondageState state = MCACompat.getKidnappedState(entity);

            if (state != null && state.isGagged()) {
                ItemStack gag = state.getEquipment(BodyRegionV2.MOUTH);
                String originalText = message.getString();
                String gaggedText = GagTalkManager.transformToGaggedSpeech(
                    originalText,
                    gag
                );

                TiedUpMod.LOGGER.debug(
                    "[MCA] Applied gagtalk transformation for villager"
                );
                return Component.literal(gaggedText);
            }
        } catch (Exception e) {
            TiedUpMod.LOGGER.debug(
                "[MCA] transformMessage failed: {}",
                e.getMessage()
            );
        }

        return message;
    }

    /**
     * Intercept playWelcomeSound to block greeting sounds when gagged.
     *
     * <p>MCA calls playWelcomeSound() in interactAt() when a player interacts
     * with a villager. This plays the "hi"/"hello" greeting sound.
     */
    @Inject(
        method = "playWelcomeSound",
        at = @At("HEAD"),
        cancellable = true,
        remap = false,
        require = 0
    )
    private void tiedup$blockWelcomeSound(CallbackInfo ci) {
        try {
            LivingEntity entity = (LivingEntity) (Object) this;
            IBondageState state = MCACompat.getKidnappedState(entity);

            if (state != null && state.isGagged()) {
                TiedUpMod.LOGGER.debug(
                    "[MCA] playWelcomeSound blocked for gagged villager"
                );
                ci.cancel();
            }
        } catch (Exception e) {
            TiedUpMod.LOGGER.debug(
                "[MCA] playWelcomeSound check failed: {}",
                e.getMessage()
            );
        }
    }

    /**
     * Intercept playSurprisedSound to block surprised sounds when gagged.
     */
    @Inject(
        method = "playSurprisedSound",
        at = @At("HEAD"),
        cancellable = true,
        remap = false,
        require = 0
    )
    private void tiedup$blockSurprisedSound(CallbackInfo ci) {
        try {
            LivingEntity entity = (LivingEntity) (Object) this;
            IBondageState state = MCACompat.getKidnappedState(entity);

            if (state != null && state.isGagged()) {
                TiedUpMod.LOGGER.debug(
                    "[MCA] playSurprisedSound blocked for gagged villager"
                );
                ci.cancel();
            }
        } catch (Exception e) {
            TiedUpMod.LOGGER.debug(
                "[MCA] playSurprisedSound check failed: {}",
                e.getMessage()
            );
        }
    }
}
