import { beforeEach, describe, expect, it } from 'vitest'

import {
  formatCodexUsage,
  getCodexUsage,
  recordCodexCapHit,
  recordCodexUsageHeaders,
  resetCodexUsageSnapshot,
} from '../codexRateLimits.js'

describe('codexRateLimits', () => {
  beforeEach(() => {
    resetCodexUsageSnapshot()
  })

  it('parses headers into a snapshot with primary + secondary buckets', () => {
    const now = Math.floor(Date.now() / 1000)
    const headers = new Headers({
      'x-codex-primary-used-percent': '42.5',
      'x-codex-primary-window-minutes': '300',
      'x-codex-primary-reset-at': String(now + 3600),
      'x-codex-secondary-used-percent': '10',
      'x-codex-secondary-window-minutes': '10080',
      'x-codex-secondary-reset-after-seconds': '600',
    })
    recordCodexUsageHeaders(headers)
    const snap = getCodexUsage()
    expect(snap?.primary?.usedPercent).toBe(42.5)
    expect(snap?.primary?.windowMinutes).toBe(300)
    expect(snap?.primary?.resetAt).toBeGreaterThan(Date.now() + 3_000_000)
    expect(snap?.secondary?.windowMinutes).toBe(10080)
    expect(snap?.secondary?.resetAt).toBeGreaterThan(Date.now())
  })

  it('ignores headers with no codex keys', () => {
    recordCodexUsageHeaders(new Headers({ 'content-type': 'application/json' }))
    expect(getCodexUsage()).toBeNull()
  })

  it('records cap hits with plan_type and reset', () => {
    const resetsAt = Math.floor(Date.now() / 1000) + 3600
    recordCodexCapHit({ planType: 'plus', resetsAt })
    const snap = getCodexUsage()
    expect(snap?.capHitPlanType).toBe('plus')
    expect(snap?.capResetsAt).toBe(resetsAt * 1000)
  })

  it('formatCodexUsage returns a human message when empty', () => {
    expect(formatCodexUsage(null)).toMatch(/No Codex usage data/)
  })

  it('formatCodexUsage formats populated snapshots', () => {
    recordCodexUsageHeaders(
      new Headers({
        'x-codex-primary-used-percent': '80',
        'x-codex-primary-window-minutes': '300',
      }),
    )
    const text = formatCodexUsage(getCodexUsage())
    expect(text).toContain('Primary: 80.0%')
    expect(text).toContain('300min window')
  })
})
