import type {CrumbReactionSummary} from '@crumbs/core/schemas'
import {describe, expect, test} from 'bun:test'

import {applyMyReaction} from '@/lib/reactions'

type S = CrumbReactionSummary

describe('applyMyReaction', () => {
  test('adds my first reaction to a crumb with none', () => {
    expect(applyMyReaction([], '🔥')).toEqual([
      {emoji: '🔥', count: 1, mine: true},
    ])
  })

  test('joins others already on the emoji', () => {
    const before: S[] = [{emoji: '🔥', count: 2, mine: false}]
    expect(applyMyReaction(before, '🔥')).toEqual([
      {emoji: '🔥', count: 3, mine: true},
    ])
  })

  test('switching emoji moves my vote, dropping an emptied summary', () => {
    const before: S[] = [{emoji: '🔥', count: 1, mine: true}]
    expect(applyMyReaction(before, '❤️')).toEqual([
      {emoji: '❤️', count: 1, mine: true},
    ])
  })

  test('switching keeps others on the old emoji', () => {
    const before: S[] = [{emoji: '🔥', count: 2, mine: true}]
    expect(applyMyReaction(before, '❤️')).toEqual([
      {emoji: '🔥', count: 1, mine: false},
      {emoji: '❤️', count: 1, mine: true},
    ])
  })

  test('clearing removes my vote, dropping an emptied summary', () => {
    const before: S[] = [{emoji: '🔥', count: 1, mine: true}]
    expect(applyMyReaction(before, null)).toEqual([])
  })

  test('clearing keeps others on the emoji', () => {
    const before: S[] = [{emoji: '🔥', count: 2, mine: true}]
    expect(applyMyReaction(before, null)).toEqual([
      {emoji: '🔥', count: 1, mine: false},
    ])
  })

  test('re-selecting the same emoji is a no-op (idempotent replay)', () => {
    const before: S[] = [{emoji: '🔥', count: 1, mine: true}]
    expect(applyMyReaction(before, '🔥')).toBe(before)
  })

  test('clearing when I never reacted is a no-op', () => {
    const before: S[] = [{emoji: '🔥', count: 1, mine: false}]
    expect(applyMyReaction(before, null)).toBe(before)
  })

  test('preserves the order of existing summaries', () => {
    const before: S[] = [
      {emoji: '🔥', count: 3, mine: false},
      {emoji: '❤️', count: 2, mine: true},
    ]
    expect(applyMyReaction(before, '🔥')).toEqual([
      {emoji: '🔥', count: 4, mine: true},
      {emoji: '❤️', count: 1, mine: false},
    ])
  })
})
