/*
 * Derived from Epic Fight (https://github.com/Epic-Fight/epicfight)
 * by the Epic Fight Team, licensed under GPLv3.
 * Modifications © 2026 TiedUp! Remake Contributors, distributed under GPLv3.
 */

package com.tiedup.remake.rig.patch;

import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.entity.Entity;
import net.minecraftforge.event.AttachCapabilitiesEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;

import com.tiedup.remake.core.TiedUpMod;
import com.tiedup.remake.rig.TiedUpRigConstants;

/**
 * Subscriber Forge qui attache un {@link EntityPatchProvider} sur chaque
 * {@link Entity} dont l'{@link net.minecraft.world.entity.EntityType} est
 * enregistré dans {@link EntityPatchProvider#CAPABILITIES CAPABILITIES}
 * (Phase 2 : PLAYER uniquement).
 *
 * <p>Pattern EF {@code yesman.epicfight.events.CapabilityEvents:36-59} mais
 * simplifié : pas de dual-capability pour CAPABILITY_SKILL (combat strippé).</p>
 *
 * <p><b>Init paresseux</b> : l'{@code onConstructed} de {@link EntityPatch}
 * ne fait PAS de cross-capability lookup (pas de
 * {@code entity.getCapability(V2_BONDAGE_EQUIPMENT)}) pour éviter toute race
 * avec l'ordre d'attachement inter-mods Forge. Voir adversarial review
 * 2026-04-22 §2 pour le raisonnement.</p>
 */
@Mod.EventBusSubscriber(modid = TiedUpMod.MOD_ID)
public class TiedUpCapabilityEvents {

	private static final ResourceLocation ENTITY_CAPABILITY_KEY =
		ResourceLocation.fromNamespaceAndPath(TiedUpMod.MOD_ID, "rig_entity_cap");

	@SuppressWarnings({ "unchecked", "rawtypes" })
	@SubscribeEvent
	public static void attachEntityCapability(AttachCapabilitiesEvent<Entity> event) {
		Entity entity = event.getObject();

		// Skip si déjà attaché par un autre subscriber (ex. datapack override via
		// CUSTOM_CAPABILITIES) — évite double-attach silencieux.
		EntityPatch oldPatch = TiedUpCapabilities.getEntityPatch(entity, EntityPatch.class);
		if (oldPatch != null) {
			return;
		}

		EntityPatchProvider provider = new EntityPatchProvider(entity);
		if (!provider.hasCapability()) {
			return; // pas dans la whitelist (VILLAGER MCA, mobs non TiedUp, etc.)
		}

		EntityPatch patch = provider.getCapability(
			TiedUpCapabilities.CAPABILITY_ENTITY, null
		).orElse(null);

		if (patch == null) {
			TiedUpRigConstants.LOGGER.warn(
				"TiedUpCapabilityEvents: EntityPatchProvider reported hasCapability but CAPABILITY_ENTITY empty for {}",
				entity.getType()
			);
			return;
		}

		// Eager init (pattern EF) : construire l'Animator + Armature avant que
		// l'entity commence son premier tick.
		patch.onConstructed(entity);
		event.addCapability(ENTITY_CAPABILITY_KEY, provider);

		// CRITICAL : invalide la LazyOptional au respawn / dim change, sinon
		// chaque mort fuit patch + animator + armature. Pattern Forge standard
		// (cf. V2BondageEquipmentProvider.invalidate, CapabilityEventHandler:50).
		event.addListener(provider::invalidate);
	}
}
