import { describe, expect, test } from 'bun:test'

import {
  buildCodexUsageRows,
  formatCodexPlanType,
  getCodexUsageUrl,
  normalizeCodexUsagePayload,
} from './codexUsage.js'

describe('normalizeCodexUsagePayload', () => {
  test('normalizes live Codex usage payloads from /backend-api/wham/usage', () => {
    const usage = normalizeCodexUsagePayload({
      plan_type: 'plus',
      rate_limit: {
        primary_window: {
          used_percent: 38,
          limit_window_seconds: 18_000,
          reset_at: 1_775_154_358,
        },
        secondary_window: {
          used_percent: 32,
          limit_window_seconds: 604_800,
          reset_at: 1_775_685_041,
        },
      },
      code_review_rate_limit: {
        primary_window: {
          used_percent: 0,
          limit_window_seconds: 604_800,
          reset_at: 1_775_744_471,
        },
        secondary_window: null,
      },
      credits: {
        has_credits: false,
        unlimited: false,
        balance: '0',
      },
    })

    expect(usage.planType).toBe('plus')
    expect(usage.snapshots).toHaveLength(2)
    expect(usage.snapshots[0]).toMatchObject({
      limitName: 'codex',
      primary: {
        usedPercent: 38,
        windowMinutes: 300,
      },
      secondary: {
        usedPercent: 32,
        windowMinutes: 10_080,
      },
    })
    expect(usage.snapshots[1]).toMatchObject({
      limitName: 'code review',
      primary: {
        usedPercent: 0,
        windowMinutes: 10_080,
      },
    })
  })

  test('supports direct protocol-style snapshot collections', () => {
    const usage = normalizeCodexUsagePayload({
      rateLimitsByLimitId: {
        codex: {
          limit_name: 'codex',
          primary: {
            used_percent: 12,
            window_minutes: 300,
            resets_at: 1_700_000_000,
          },
          credits: {
            has_credits: true,
            unlimited: false,
            balance: '25',
          },
        },
      },
    })

    expect(usage.snapshots).toEqual([
      {
        limitName: 'codex',
        primary: {
          usedPercent: 12,
          windowMinutes: 300,
          resetsAt: new Date(1_700_000_000 * 1000).toISOString(),
        },
        secondary: undefined,
        credits: {
          hasCredits: true,
          unlimited: false,
          balance: '25',
        },
      },
    ])
  })
})

describe('buildCodexUsageRows', () => {
  test('builds Codex-like labels for primary and secondary windows', () => {
    const rows = buildCodexUsageRows([
      {
        limitName: 'codex',
        primary: {
          usedPercent: 38,
          windowMinutes: 300,
          resetsAt: '2026-04-02T10:00:00.000Z',
        },
        secondary: {
          usedPercent: 32,
          windowMinutes: 10_080,
          resetsAt: '2026-04-09T10:00:00.000Z',
        },
      },
      {
        limitName: 'code review',
        primary: {
          usedPercent: 0,
          windowMinutes: 10_080,
          resetsAt: '2026-04-09T10:00:00.000Z',
        },
      },
    ])

    expect(rows).toEqual([
      {
        kind: 'window',
        label: '5h limit',
        usedPercent: 38,
        resetsAt: '2026-04-02T10:00:00.000Z',
      },
      {
        kind: 'window',
        label: 'Weekly limit',
        usedPercent: 32,
        resetsAt: '2026-04-09T10:00:00.000Z',
      },
      {
        kind: 'window',
        label: 'Code review Weekly limit',
        usedPercent: 0,
        resetsAt: '2026-04-09T10:00:00.000Z',
      },
    ])
  })

  test('renders credits rows only when credits are available', () => {
    const rows = buildCodexUsageRows([
      {
        limitName: 'codex',
        credits: {
          hasCredits: true,
          unlimited: false,
          balance: '25.2',
        },
      },
      {
        limitName: 'code review',
        credits: {
          hasCredits: true,
          unlimited: true,
        },
      },
      {
        limitName: 'other',
        credits: {
          hasCredits: true,
          unlimited: false,
          balance: '0',
        },
      },
    ])

    expect(rows).toEqual([
      {
        kind: 'text',
        label: 'Credits',
        value: '25 credits',
      },
      {
        kind: 'text',
        label: 'Code review limit',
        value: '',
      },
      {
        kind: 'text',
        label: 'Credits',
        value: 'Unlimited',
      },
    ])
  })
})

describe('Codex usage helpers', () => {
  test('formats plan labels and usage endpoint url', () => {
    expect(formatCodexPlanType('team_max')).toBe('Team Max')
    expect(getCodexUsageUrl()).toBe('https://chatgpt.com/backend-api/wham/usage')
    expect(getCodexUsageUrl('https://chatgpt.com/backend-api/codex')).toBe(
      'https://chatgpt.com/backend-api/wham/usage',
    )
  })
})
