import { describe, expect, it } from 'vitest'
import { resolveCodexUsageWindow } from '@/utils/codexUsage'

describe('resolveCodexUsageWindow', () => {
  it('快照为空时返回空窗口', () => {
    const result = resolveCodexUsageWindow(null, '5h', new Date('2026-02-20T08:00:00Z'))
    expect(result).toEqual({ usedPercent: null, resetAt: null })
  })

  it('优先使用后端提供的绝对重置时间', () => {
    const now = new Date('2026-02-20T08:00:00Z')
    const result = resolveCodexUsageWindow(
      {
        codex_5h_used_percent: 55,
        codex_5h_reset_at: '2026-02-20T10:00:00Z',
        codex_5h_reset_after_seconds: 1
      },
      '5h',
      now
    )

    expect(result.usedPercent).toBe(55)
    expect(result.resetAt).toBe('2026-02-20T10:00:00.000Z')
  })

  it('窗口已过期时自动归零', () => {
    const now = new Date('2026-02-20T08:00:00Z')
    const result = resolveCodexUsageWindow(
      {
        codex_7d_used_percent: 100,
        codex_7d_reset_at: '2026-02-20T07:00:00Z'
      },
      '7d',
      now
    )

    expect(result.usedPercent).toBe(0)
    expect(result.resetAt).toBe('2026-02-20T07:00:00.000Z')
  })

  it('无绝对时间时使用 updated_at + seconds 回退计算', () => {
    const now = new Date('2026-02-20T07:00:00Z')
    const result = resolveCodexUsageWindow(
      {
        codex_5h_used_percent: 20,
        codex_5h_reset_after_seconds: 3600,
        codex_usage_updated_at: '2026-02-20T06:30:00Z'
      },
      '5h',
      now
    )

    expect(result.usedPercent).toBe(20)
    expect(result.resetAt).toBe('2026-02-20T07:30:00.000Z')
  })

  it('支持 legacy primary/secondary 字段映射', () => {
    const now = new Date('2026-02-20T07:05:00Z')
    const result5h = resolveCodexUsageWindow(
      {
        codex_primary_window_minutes: 10080,
        codex_primary_used_percent: 70,
        codex_primary_reset_after_seconds: 86400,
        codex_secondary_window_minutes: 300,
        codex_secondary_used_percent: 15,
        codex_secondary_reset_after_seconds: 1200,
        codex_usage_updated_at: '2026-02-20T07:00:00Z'
      },
      '5h',
      now
    )
    const result7d = resolveCodexUsageWindow(
      {
        codex_primary_window_minutes: 10080,
        codex_primary_used_percent: 70,
        codex_primary_reset_after_seconds: 86400,
        codex_secondary_window_minutes: 300,
        codex_secondary_used_percent: 15,
        codex_secondary_reset_after_seconds: 1200,
        codex_usage_updated_at: '2026-02-20T07:00:00Z'
      },
      '7d',
      now
    )

    expect(result5h.usedPercent).toBe(15)
    expect(result5h.resetAt).toBe('2026-02-20T07:20:00.000Z')
    expect(result7d.usedPercent).toBe(70)
    expect(result7d.resetAt).toBe('2026-02-21T07:00:00.000Z')
  })

  it('legacy 5h 在 primary<=360 时优先 primary 并支持字符串数字', () => {
    const result = resolveCodexUsageWindow(
      {
        codex_primary_window_minutes: '300',
        codex_primary_used_percent: '21',
        codex_primary_reset_after_seconds: '1800',
        codex_secondary_window_minutes: '10080',
        codex_secondary_used_percent: '99',
        codex_secondary_reset_after_seconds: '99999',
        codex_usage_updated_at: '2026-02-20T08:00:00Z'
      },
      '5h',
      new Date('2026-02-20T08:10:00Z')
    )

    expect(result.usedPercent).toBe(21)
    expect(result.resetAt).toBe('2026-02-20T08:30:00.000Z')
  })

  it('legacy 5h 在无窗口信息时回退 secondary', () => {
    const result = resolveCodexUsageWindow(
      {
        codex_secondary_used_percent: 19,
        codex_secondary_reset_after_seconds: 120,
        codex_usage_updated_at: '2026-02-20T08:00:00Z'
      },
      '5h',
      new Date('2026-02-20T08:00:01Z')
    )

    expect(result.usedPercent).toBe(19)
    expect(result.resetAt).toBe('2026-02-20T08:02:00.000Z')
  })

  it('legacy 场景下 secondary 为 7d 时能正确识别', () => {
    const now = new Date('2026-02-20T07:30:00Z')
    const result = resolveCodexUsageWindow(
      {
        codex_primary_window_minutes: 300,
        codex_primary_used_percent: 5,
        codex_primary_reset_after_seconds: 600,
        codex_secondary_window_minutes: 10080,
        codex_secondary_used_percent: 66,
        codex_secondary_reset_after_seconds: 7200,
        codex_usage_updated_at: '2026-02-20T07:00:00Z'
      },
      '7d',
      now
    )

    expect(result.usedPercent).toBe(66)
    expect(result.resetAt).toBe('2026-02-20T09:00:00.000Z')
  })

  it('绝对时间非法时回退到 updated_at + seconds', () => {
    const now = new Date('2026-02-20T07:40:00Z')
    const result = resolveCodexUsageWindow(
      {
        codex_5h_used_percent: 33,
        codex_5h_reset_at: 'not-a-date',
        codex_5h_reset_after_seconds: 900,
        codex_usage_updated_at: '2026-02-20T07:30:00Z'
      },
      '5h',
      now
    )

    expect(result.usedPercent).toBe(33)
    expect(result.resetAt).toBe('2026-02-20T07:45:00.000Z')
  })

  it('updated_at 非法且无绝对时间时 resetAt 返回 null', () => {
    const result = resolveCodexUsageWindow(
      {
        codex_5h_used_percent: 10,
        codex_5h_reset_after_seconds: 123,
        codex_usage_updated_at: 'invalid-time'
      },
      '5h',
      new Date('2026-02-20T08:00:00Z')
    )

    expect(result.usedPercent).toBe(10)
    expect(result.resetAt).toBeNull()
  })

  it('reset_after_seconds 为负数时按 0 秒处理', () => {
    const result = resolveCodexUsageWindow(
      {
        codex_5h_used_percent: 80,
        codex_5h_reset_after_seconds: -30,
        codex_usage_updated_at: '2026-02-20T08:00:00Z'
      },
      '5h',
      new Date('2026-02-20T07:59:00Z')
    )

    expect(result.usedPercent).toBe(80)
    expect(result.resetAt).toBe('2026-02-20T08:00:00.000Z')
  })

  it('百分比缺失时仍可计算 resetAt 供倒计时展示', () => {
    const result = resolveCodexUsageWindow(
      {
        codex_7d_reset_after_seconds: 60,
        codex_usage_updated_at: '2026-02-20T08:00:00Z'
      },
      '7d',
      new Date('2026-02-20T08:00:01Z')
    )

    expect(result.usedPercent).toBeNull()
    expect(result.resetAt).toBe('2026-02-20T08:01:00.000Z')
  })
})
