import type {CrumbReactionSummary} from '@crumbs/core/schemas'

// recompute a crumb's reaction summaries after the viewer sets their own
// reaction to `emoji` (or clears it with null) — a local mirror of the server's
// aggregate so an offline react shows instantly. the viewer holds at most one
// reaction, so this moves their single vote off any previous emoji and onto the
// new one: a summary that drops to zero disappears, one that newly appears is
// added, and existing order is preserved. pure + idempotent (re-selecting the
// same emoji is a no-op), so it composes with an at-least-once outbox replay
export const applyMyReaction = (
  reactions: CrumbReactionSummary[],
  emoji: string | null,
): CrumbReactionSummary[] => {
  const mine = reactions.find((r) => r.mine)?.emoji ?? null
  if (mine === emoji) return reactions

  // drop my vote from the emoji I had, removing the summary if it empties
  const withoutMine = mine
    ? reactions
        .map((r) =>
          r.emoji === mine
            ? {...r, count: r.count - 1, mine: false}
            : r,
        )
        .filter((r) => r.count > 0)
    : reactions

  if (!emoji) return withoutMine

  // add my vote to the new emoji, joining others on it or starting it fresh
  return withoutMine.some((r) => r.emoji === emoji)
    ? withoutMine.map((r) =>
        r.emoji === emoji
          ? {...r, count: r.count + 1, mine: true}
          : r,
      )
    : [...withoutMine, {emoji, count: 1, mine: true}]
}
