import { world, system } from "@minecraft/server";

/**
 * Pokémon Revival - Fishing (Raycast)
 * - Right-click while holding a rod and aiming at water to fish (works like vanilla)
 * - Requires 1 bait in inventory (consumed on cast)
 * - Rod controls rarity tier weights
 * - Bait controls encounter pools
 */

// --- CONFIG ---
const ROD_WEIGHTS = {
  "pr:old_rod":   { common: 85, uncommon: 14, rare: 1  },
  "pr:good_rod":  { common: 70, uncommon: 25, rare: 5  },
  "pr:super_rod": { common: 55, uncommon: 30, rare: 15 },
  "pr:fishing_rod": { common: 75, uncommon: 22, rare: 3 },
};


const BAIT_TABLES = {
  "pr:oran_bait": {
    common:   ["pr:magikarp", "pr:goldeen", "pr:shellder"],
    uncommon: ["pr:horsea", "pr:staryu", "pr:seel"],
    rare:     ["pr:lapras", "pr:gyarados"],
  },
  "pr:razz_bait": {
    common:   ["pr:magikarp", "pr:horsea", "pr:shellder"],
    uncommon: ["pr:seadra", "pr:staryu", "pr:seel"],
    rare:     ["pr:lapras", "pr:gyarados", "pr:omanyte"],
  },
  "pr:nanab_bait": {
    common:   ["pr:goldeen", "pr:shellder", "pr:seel"],
    uncommon: ["pr:staryu", "pr:horsea", "pr:seadra"],
    rare:     ["pr:kabuto", "pr:omanyte", "pr:lapras"],
  },
  "pr:pinab_bait": {
    common:   ["pr:magikarp", "pr:goldeen", "pr:staryu"],
    uncommon: ["pr:horsea", "pr:seadra", "pr:seel"],
    rare:     ["pr:gyarados", "pr:feraligatr", "pr:kabuto"],
  },

  // Fallback bait tables (if you add more bait items, either add a table here,
  // or they'll use DEFAULT_TABLE below).
};


const DEFAULT_TABLE = {
  common:   ["pr:magikarp", "pr:goldeen", "pr:shellder"],
  uncommon: ["pr:horsea", "pr:staryu", "pr:seel"],
  rare:     ["pr:lapras", "pr:gyarados"],
};


// --- INTERNAL ---
const lastCastTick = new Map(); // player.id -> tick

function pickWeightedTier(weights) {
  const entries = Object.entries(weights);
  let total = 0;
  for (const [, w] of entries) total += w;
  if (total <= 0) return "common";
  let r = Math.random() * total;
  for (const [tier, w] of entries) {
    r -= w;
    if (r <= 0) return tier;
  }
  return entries[0]?.[0] ?? "common";
}

function pickRandom(list) {
  return list[Math.floor(Math.random() * list.length)];
}

function findAnyBait(container) {
  for (let i = 0; i < container.size; i++) {
    const it = container.getItem(i);
    if (!it) continue;
    if (BAIT_TABLES[it.typeId] || it.typeId.endsWith("_bait")) {
      return { slot: i, typeId: it.typeId, item: it };
    }
  }
  return null;
}

function consumeOne(container, slot) {
  const it = container.getItem(slot);
  if (!it) return;
  if (it.amount <= 1) container.setItem(slot, undefined);
  else {
    it.amount -= 1;
    container.setItem(slot, it);
  }
}

function tryFish(player, waterBlockLoc, rodId) {
  // inventory
  let container;
  try {
    container = player.getComponent("minecraft:inventory")?.container;
  } catch {
    container = null;
  }
  if (!container) return;

  const bait = findAnyBait(container);
  if (!bait) {
    try { player.onScreenDisplay.setActionBar("§cYou need bait to fish."); } catch {}
    return;
  }

  // consume bait
  consumeOne(container, bait.slot);

  const table = BAIT_TABLES[bait.typeId] ?? DEFAULT_TABLE;
  const tier = pickWeightedTier(ROD_WEIGHTS[rodId]);
  const list = (table[tier] && table[tier].length) ? table[tier] : table.common;
  const chosen = pickRandom(list);

  // spawn slightly above water surface
  const spawnPos = { x: waterBlockLoc.x + 0.5, y: waterBlockLoc.y + 1.0, z: waterBlockLoc.z + 0.5 };

  let spawned = null;
  try {
    spawned = player.dimension.spawnEntity(chosen, spawnPos);
  } catch {
    spawned = null;
  }

  if (!spawned) {
    // Fallback to command summon (helps if spawnEntity fails for some custom entities)
    try {
      player.dimension.runCommand(`summon ${chosen} ${spawnPos.x} ${spawnPos.y} ${spawnPos.z}`);
    } catch {
      try { player.onScreenDisplay.setActionBar("§cFishing failed (bad Pokémon identifier in table)."); } catch {}
      return;
    }
  } else {
    try { spawned.addTag("pr:fished"); } catch {}
  }

  // feedback
  try { player.playSound("minecraft:entity.fishing_bobber.splash", { volume: 1.0, pitch: 1.0 }); } catch {}
  try { player.onScreenDisplay.setActionBar(`§aA wild Pokémon appeared! §7(${tier})`); } catch {}
}

// --- ENTRYPOINTS ---
// Called by both the generic itemUse listener (vanilla-style) AND the fishing-pack custom item components.
export function handleFishingRodUse(player, rodId) {
  if (!player || player.typeId !== "minecraft:player") return;
  if (!ROD_WEIGHTS[rodId]) return;

  // simple anti-spam cooldown
  const now = system.currentTick;
  const last = lastCastTick.get(player.id) ?? -9999;
  if (now - last < 10) return; // ~0.5s
  lastCastTick.set(player.id, now);

  // raycast to water block
  const hit = player.getBlockFromViewDirection({ maxDistance: 10 });
  if (!hit || !hit.block) return;

  const block = hit.block;
  if (block.typeId !== "minecraft:water") return;

  tryFish(player, block.location, rodId);
}

// Fallback: if an item doesn't use custom components, itemUse still works.
world.afterEvents.itemUse.subscribe((ev) => {
  const item = ev.itemStack;
  if (!item) return;
  handleFishingRodUse(ev.source, item.typeId);
});
