import { describe, it, expect, vi, afterEach } from 'vitest'
import { relTime, formatWhen, fmtSchedule } from '../src/renderer/src/lib/datetime'

afterEach(() => {
  vi.useRealTimers()
})

describe('relTime', () => {
  it('returns "never" for a missing timestamp', () => {
    expect(relTime(undefined)).toBe('never')
    expect(relTime(0)).toBe('never')
  })

  it('buckets into just now / minutes / hours / days', () => {
    const now = new Date('2026-06-30T12:00:00Z').getTime()
    vi.useFakeTimers()
    vi.setSystemTime(now)
    expect(relTime(now - 20 * 1000)).toBe('just now') // < 1 min
    expect(relTime(now - 5 * 60_000)).toBe('5 min ago')
    expect(relTime(now - 3 * 3_600_000)).toBe('3 h ago')
    expect(relTime(now - 2 * 86_400_000)).toBe('2 d ago')
  })
})

describe('formatWhen', () => {
  it('labels today and yesterday with the time, older with a date', () => {
    const now = new Date('2026-06-30T12:00:00Z').getTime()
    vi.useFakeTimers()
    vi.setSystemTime(now)
    expect(formatWhen(now)).toMatch(/^Today, /)
    expect(formatWhen(now - 86_400_000)).toMatch(/^Yesterday, /)
    // A clearly-older timestamp falls through to an absolute date (with year).
    expect(formatWhen(new Date('2025-01-05T09:00:00Z').getTime())).toMatch(/2025/)
  })
})

describe('fmtSchedule', () => {
  it('formats a valid timestamp and never throws', () => {
    expect(fmtSchedule(new Date('2026-06-30T15:04:00Z').getTime())).toMatch(/2026/)
    // Defensive: NaN can't be formatted but must not throw.
    expect(typeof fmtSchedule(Number.NaN)).toBe('string')
  })
})
