import { describe, expect, it } from 'vitest'
import { shallowDiffSummary, isEmptyDiffSummary } from './diff'

describe('shallowDiffSummary', () => {
  it('returns null when both inputs are null', () => {
    expect(shallowDiffSummary(null, null)).toBeNull()
    expect(shallowDiffSummary(undefined, undefined)).toBeNull()
    expect(shallowDiffSummary(null, undefined)).toBeNull()
  })

  it('reports added keys when before is empty/null', () => {
    const s = shallowDiffSummary(null, { code: 'A', name: 'Alpha' })
    expect(s).toEqual({ added: ['code', 'name'], removed: [], changed: [] })
  })

  it('reports removed keys when after is empty/null', () => {
    const s = shallowDiffSummary({ code: 'A', name: 'Alpha' }, null)
    expect(s).toEqual({ added: [], removed: ['code', 'name'], changed: [] })
  })

  it('reports changed keys when values differ', () => {
    const s = shallowDiffSummary({ code: 'A', count: 1 }, { code: 'A', count: 2 })
    expect(s).toEqual({ added: [], removed: [], changed: ['count'] })
  })

  it('handles mixed +/-/~ in one call', () => {
    const s = shallowDiffSummary(
      { code: 'A', count: 1, oldField: 'x' },
      { code: 'A', count: 2, newField: 'y' },
    )
    expect(s).toEqual({
      added: ['newField'],
      removed: ['oldField'],
      changed: ['count'],
    })
  })

  it('treats nested-object change as one changed entry on the outer key', () => {
    const s = shallowDiffSummary(
      { code: 'A', meta: { lat: 55, lon: 37 } },
      { code: 'A', meta: { lat: 55, lon: 38 } },
    )
    expect(s).toEqual({ added: [], removed: [], changed: ['meta'] })
  })

  it('reports empty buckets when payloads are deeply equal', () => {
    const s = shallowDiffSummary({ code: 'A', count: 1 }, { code: 'A', count: 1 })
    expect(s).toEqual({ added: [], removed: [], changed: [] })
    expect(s && isEmptyDiffSummary(s)).toBe(true)
  })
})

describe('isEmptyDiffSummary', () => {
  it('returns true when all three buckets are empty', () => {
    expect(isEmptyDiffSummary({ added: [], removed: [], changed: [] })).toBe(true)
  })

  it('returns false when any bucket has entries', () => {
    expect(isEmptyDiffSummary({ added: ['x'], removed: [], changed: [] })).toBe(false)
    expect(isEmptyDiffSummary({ added: [], removed: ['x'], changed: [] })).toBe(false)
    expect(isEmptyDiffSummary({ added: [], removed: [], changed: ['x'] })).toBe(false)
  })
})
