async function handleSwitchAfterReclaim(btn: ButtonInteraction): Promise<void> {
  const prefix        = btn.customId.startsWith("companion_switch:") ? "companion_switch:" : "switch_after_reclaim:";
  const withoutPrefix = btn.customId.slice(prefix.length);
  const firstColon    = withoutPrefix.indexOf(":");
  const userKey       = withoutPrefix.slice(0, firstColon);
  const rest          = withoutPrefix.slice(firstColon + 1);
  const lastColon     = rest.lastIndexOf(":");
  const charName      = rest.slice(0, lastColon);
  const prevVoteType  = (rest.slice(lastColon + 1) || "yes") as "yes" | "no";

  const chars = JSON.parse(
    fs.readFileSync(path.join(__dirname, "../../data/characters.json"), "utf8")
  );

  let resolvedChar: any = null;
  let borrowedFrom: string | null = null;

  // Try own char first
  const ownEntry = chars[userKey]?.characters?.find((c: any) => c.name === charName);
  if (ownEntry) {
    setActiveCharacter(userKey, charName);
    clearSessionBorrowForUser(userKey);
    clearPersistentPreference(userKey); 
    resolvedChar = ownEntry;
  } else {
    // Try shared char
    for (const [ownerKey, data] of Object.entries(chars) as [string, any][]) {
      const char = data.characters?.find(
        (c: any) => c.name === charName && c.sharedWith?.includes(userKey)
      );
      if (char) {
        setPersistentPreference(userKey, ownerKey, charName);
        clearSessionBorrowForUser(userKey);
        resolvedChar  = char;
        borrowedFrom  = ownerKey;
        break;
      }
    }
  }

  if (!resolvedChar) {
    await btn.reply({ content: `❌ Could not switch to **${charName}**.`, ephemeral: true });
    return;
  }

  // Re-add to poll with previous vote type
  const slot  = [...polls.keys()][0];
  const state = slot !== undefined ? polls.get(slot) : null;

  let existingVoteId: string | null = null;
  if (state) {
    for (const [id, entry] of [...state.yes.entries(), ...state.no.entries()]) {
      if (entry.userKey === userKey) {
        existingVoteId = id;
        break;
      }
    }
  }

  // Conflict check
  if (state && resolvedChar) {
    for (const [id, entry] of state.yes.entries()) {
      if (id !== existingVoteId && id !== btn.user.id && 
          entry.characterName === resolvedChar.name && 
          entry.userKey !== userKey) {
          await btn.reply({
            content: `❌ ${format.char(resolvedChar)} is already in the poll by another player.`,
            ephemeral: true,
          });
          return;
      }
    }
  }
  
  if (state && !state.locked && state.confirmed === null) {
    const { char } = getEffectiveCharacter(userKey);
    const now       = nowFormatted();
    const publicMsg = resolveMessage("public", prevVoteType, 1, userKey, null, null);
    const voteEntry = {
      userKey,
      displayName:     charName,
      characterName:   char?.name ?? charName,
      characterClass:  char?.class ?? resolvedChar.class,
      characterLevel:  char?.level ?? resolvedChar.level,
      characterNation: char?.nation ?? resolvedChar.nation,
      borrowedFrom:    borrowedFrom ?? undefined,
      discordId:       btn.user.id,
      votedAt:         now,
      publicMessage:   publicMsg ?? undefined,
    };

    // Find and reuse existing vote ID — avoids duplicate entries
    let existingVoteId: string | null = null;
    for (const [id, entry] of [...state.yes.entries(), ...state.no.entries()]) {
      if (entry.userKey === userKey) {
        if (!existingVoteId) existingVoteId = id;
        state.yes.delete(id);
        state.no.delete(id);
      }
    }
    const voteId = existingVoteId ?? btn.user.id;

    if (prevVoteType === "yes") {
      state.yes.set(voteId, voteEntry);
    } else {
      state.no.set(voteId, voteEntry);
    }

    console.log(`[switch_reclaim] cleaning up for userKey=${userKey}`);
    console.log(`[switch_reclaim] yes keys:`, [...state.yes.entries()].map(([id, e]) => `${id}:${e.userKey}`));
    console.log(`[switch_reclaim] no keys:`,  [...state.no.entries()].map(([id, e]) => `${id}:${e.userKey}`));

    const channel = await btn.client.channels.fetch(cfg("pollChannelId")) as TextChannel;
    await updatePollMessage(channel, slot!);
  }

  const charDisplay = resolvedChar ? format.char(resolvedChar) : charName;
  const borrowNote  = borrowedFrom ? ` *(shared by ${borrowedFrom})*` : "";
  await btn.reply({
    content: `🔄 ${charDisplay}${borrowNote}${state ? ` — re-added to poll as **${prevVoteType}**.` : ""}`,
    ephemeral: true,
  });
}