package com.tiedup.remake.mixin;

import com.tiedup.remake.compat.mca.MCACompat;
import com.tiedup.remake.compat.mca.ai.chatai.TiedUpModule;
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 java.util.List;
import java.util.Optional;
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.ModifyVariable;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;

/**
 * Mixin for MCA's OpenAIChatAI to integrate TiedUp bondage context.
 *
 * <p>This mixin:
 * <ul>
 *   <li>Injects TiedUp state into the AI context (tied, gagged, blindfolded, etc.)</li>
 *   <li>Transforms AI responses with gagtalk if the villager is gagged</li>
 * </ul>
 *
 * <p>Note: Uses @Pseudo for soft dependency - only applies if MCA is present.
 */
@Pseudo
@Mixin(targets = "forge.net.mca.entity.ai.chatAI.OpenAIChatAI", remap = false)
public class MixinMCAOpenAIChatAI {

    /**
     * Inject TiedUp context after MCA's modules are applied.
     *
     * <p>We capture the 'input' list local variable and add our TiedUp context to it.
     * This is called after PlayerModule.apply() which is the last module in the chain.
     */
    @Inject(
        method = "answer",
        at = @At(
            value = "INVOKE",
            target = "Lforge/net/mca/entity/ai/chatAI/modules/PlayerModule;apply(Ljava/util/List;Lforge/net/mca/entity/VillagerEntityMCA;Lnet/minecraft/server/network/ServerPlayerEntity;)V",
            shift = At.Shift.AFTER
        ),
        locals = LocalCapture.CAPTURE_FAILSOFT,
        require = 0 // Soft requirement - don't crash if not found
    )
    private void tiedup$injectBondageContext(
        Object player, // ServerPlayerEntity
        Object villager, // VillagerEntityMCA
        String msg,
        CallbackInfoReturnable<Optional<String>> cir,
        // Local variables captured (order matters!)
        Object config,
        boolean isInHouse,
        String playerName,
        String villagerName,
        long time,
        List<?> pastDialogue,
        List<String> input
    ) {
        try {
            if (
                villager instanceof LivingEntity living &&
                player instanceof net.minecraft.world.entity.player.Player p
            ) {
                TiedUpModule.apply(input, living, p);

                TiedUpMod.LOGGER.debug(
                    "[MCA AI] Injected TiedUp context for {}",
                    living.getName().getString()
                );
            }
        } catch (Exception e) {
            TiedUpMod.LOGGER.debug(
                "[MCA AI] Failed to inject context: {}",
                e.getMessage()
            );
        }
    }

    /**
     * Transform the AI response with gagtalk if the villager is gagged.
     *
     * <p>Intercepts the return value and applies gagtalk transformation
     * using TiedUp's GagTalkManager.
     */
    @Inject(
        method = "answer",
        at = @At("RETURN"),
        cancellable = true,
        require = 0
    )
    private void tiedup$transformGaggedResponse(
        Object player, // ServerPlayerEntity
        Object villager, // VillagerEntityMCA
        String msg,
        CallbackInfoReturnable<Optional<String>> cir
    ) {
        try {
            Optional<String> result = cir.getReturnValue();
            if (result == null || result.isEmpty()) return;

            if (!(villager instanceof LivingEntity living)) return;

            IBondageState state = MCACompat.getKidnappedState(living);
            if (state == null || !state.isGagged()) return;

            // Apply gagtalk transformation
            ItemStack gag = state.getEquipment(BodyRegionV2.MOUTH);
            String gaggedResponse = GagTalkManager.transformToGaggedSpeech(
                result.get(),
                gag
            );

            TiedUpMod.LOGGER.debug("[MCA AI] Applied gagtalk to AI response");
            cir.setReturnValue(Optional.of(gaggedResponse));
        } catch (Exception e) {
            TiedUpMod.LOGGER.debug(
                "[MCA AI] Failed to transform gagged response: {}",
                e.getMessage()
            );
        }
    }
}
