import { describe, it, expect } from 'vitest'
import { parseBudgetSpec, formatBudgetLine, getBudgetWarningLevel } from '../utils/budget.js'

describe('parseBudgetSpec', () => {
  it('accepts plain dollar amount', () => {
    expect(parseBudgetSpec('5')).toEqual({ dailyLimitUSD: 5 })
    expect(parseBudgetSpec('10.50')).toEqual({ dailyLimitUSD: 10.5 })
  })

  it('accepts $-prefixed amount', () => {
    expect(parseBudgetSpec('$5')).toEqual({ dailyLimitUSD: 5 })
    expect(parseBudgetSpec('$2.75')).toEqual({ dailyLimitUSD: 2.75 })
  })

  it('strips trailing /day for convenience', () => {
    expect(parseBudgetSpec('$5/day')).toEqual({ dailyLimitUSD: 5 })
    expect(parseBudgetSpec('5/day')).toEqual({ dailyLimitUSD: 5 })
  })

  it('returns null for off/clear/none/0', () => {
    expect(parseBudgetSpec('off')).toBeNull()
    expect(parseBudgetSpec('clear')).toBeNull()
    expect(parseBudgetSpec('none')).toBeNull()
    expect(parseBudgetSpec('0')).toBeNull()
    expect(parseBudgetSpec('$0')).toBeNull()
  })

  it('rejects invalid input by returning undefined', () => {
    expect(parseBudgetSpec('abc')).toBeUndefined()
    expect(parseBudgetSpec('')).toBeUndefined()
    expect(parseBudgetSpec('-5')).toBeUndefined()
    expect(parseBudgetSpec('$$5')).toBeUndefined()
  })

  it('rejects unreasonably large amounts', () => {
    expect(parseBudgetSpec('1000000')).toBeUndefined()
  })
})

describe('getBudgetWarningLevel', () => {
  it('returns "ok" when no limit is set', () => {
    expect(getBudgetWarningLevel(null, 0)).toBe('ok')
    expect(getBudgetWarningLevel(null, 100)).toBe('ok')
  })

  it('returns "ok" below 75%', () => {
    expect(getBudgetWarningLevel({ dailyLimitUSD: 10 }, 0)).toBe('ok')
    expect(getBudgetWarningLevel({ dailyLimitUSD: 10 }, 7.4)).toBe('ok')
  })

  it('returns "warn" at 75%–99%', () => {
    expect(getBudgetWarningLevel({ dailyLimitUSD: 10 }, 7.5)).toBe('warn')
    expect(getBudgetWarningLevel({ dailyLimitUSD: 10 }, 9.99)).toBe('warn')
  })

  it('returns "over" at 100%+', () => {
    expect(getBudgetWarningLevel({ dailyLimitUSD: 10 }, 10)).toBe('over')
    expect(getBudgetWarningLevel({ dailyLimitUSD: 10 }, 15)).toBe('over')
  })
})

describe('formatBudgetLine', () => {
  it('renders a ratio with percentage when limit is set', () => {
    const line = formatBudgetLine({ dailyLimitUSD: 5 }, 1.25)
    expect(line).toContain('$1.25')
    expect(line).toContain('$5')
    expect(line).toContain('25%')
  })

  it('renders a neutral string when no limit is set', () => {
    const line = formatBudgetLine(null, 1.25)
    expect(line).toMatch(/no .*budget/i)
  })

  it('flags over-budget visibly', () => {
    const line = formatBudgetLine({ dailyLimitUSD: 5 }, 6)
    expect(line).toMatch(/over|exceed/i)
  })
})
