import { TRINKET_EFFECTS } from "./trinketEffectMap.js";
import {
  handleEffects,
  handleFallDamage,
  handleDoubleJump,
  handleDynamicLight,
  handleInvis,
  handleMagnetic,
  handleLowHealth,
  handleSmelter,
  handleAutoEat,
  handleOreFinder,
  handleBossDragon,
} from "./trinketEffectFunctions.js";
import { handleFlight } from "./flightManager.js";
const MAX_TIER = 3;

const HANDLER_MAP = {
  handleDoubleJump,
  handleFallDamage,
};

export function trinketChecker(player, items = []) {
  const activeTags = new Set();
  const trinketCounts = new Map();
  const effectTiers = {}; // key: effectName, value: total tier

  // Count how many of each trinket the player has
  for (const item of items) {
    const { typeId, amount } = item;
    trinketCounts.set(typeId, (trinketCounts.get(typeId) || 0) + amount);
  }

  // Aggregate effects from trinkets
  for (const [typeId, count] of trinketCounts) {
    const config = TRINKET_EFFECTS[typeId];
    if (!config) continue;

    const tier = Math.min(count, config.cap ?? MAX_TIER);

    // Add effect tier values
    if (config.effects) {
      for (const [effectName, effectTierValue] of Object.entries(
        config.effects
      )) {
        effectTiers[effectName] ??= 0;
        effectTiers[effectName] += effectTierValue * tier;
      }
    }

    // Apply tags if configured to be tiered
    if (config.taggable) {
      const tagBase = typeId.replace(":", "_");
      const tierTag = `${tagBase}_${tier}`;
      activeTags.add(tierTag);

      for (let i = 1; i <= MAX_TIER; i++) {
        const tagName = `${tagBase}_${i}`;
        if (i !== tier && player.hasTag(tagName)) {
          player.removeTag(tagName);
        }
      }
    }

    // Direct effect removal
    if (config.removes) {
      for (const effectId of config.removes) {
        player.removeEffect(effectId);
      }
    }

    // Handler calls
    if (config.handler && HANDLER_MAP[config.handler]) {
      HANDLER_MAP[config.handler](player);
    }
  }

  // Sync tiered tags (add missing, remove stale)
  const playerTags = player.getTags();

  // Add current relevant tags
  for (const tagName of activeTags) {
    if (!playerTags.includes(tagName)) {
      player.addTag(tagName);
    }
  }

  // Remove any stale trinket-related tags
  for (const tag of playerTags) {
    if (/^pb_gat_trinket_.*_\d$/.test(tag) && !activeTags.has(tag)) {
      player.removeTag(tag);
    }
  }

  // Run all effect handlers with the combined effect tiers
  for (const [effectName, tier] of Object.entries(effectTiers)) {
    const cappedTier = Math.min(tier, MAX_TIER);
    switch (effectName) {
      case "pearlCast":
        handleBossDragon(player);
        break;
      case "speed":
        handleEffects(player, "speed", cappedTier);
        break;
      case "strength":
        handleEffects(player, "strength", cappedTier);
        break;
      case "slow_falling":
        handleEffects(player, "slow_falling", cappedTier);
        break;
      case "fire_resistance":
        handleEffects(player, "fire_resistance", cappedTier);
        break;
      case "conduit_power":
        if (player.isInWater) {
          handleEffects(player, "conduit_power", cappedTier);
        }
        break;
      case "weaving":
        handleEffects(player, "weaving", cappedTier);
        break;
      case "jump_boost":
        handleEffects(player, "jump_boost", cappedTier);
        break;
      case "invis":
        handleInvis(player, cappedTier);
        break;
      case "light":
        handleDynamicLight(player, cappedTier);
        break;
      case "magnet":
        handleMagnetic(player, cappedTier);
        break;
      case "low_health":
        handleLowHealth(player, cappedTier);
        break;
      case "smelt":
        handleSmelter(player, cappedTier);
        break;
      case "eat":
        handleAutoEat(player, cappedTier);
        break;
      case "ores":
        handleOreFinder(player, cappedTier);
        break;
      case "flight":
        handleFlight(player);
        break;
    }
  }
}
