import { describe, it, expect } from 'vitest';
import { estimateCostUsd, PRICING } from './pricing';
import { HAIKU, SONNET, OPUS } from './models';

describe('PRICING', () => {
  it('has rows for all three analyzer models', () => {
    expect(PRICING[HAIKU]).toBeDefined();
    expect(PRICING[SONNET]).toBeDefined();
    expect(PRICING[OPUS]).toBeDefined();
  });

  it('output is more expensive than input on every model', () => {
    for (const m of [HAIKU, SONNET, OPUS] as const) {
      expect(PRICING[m].output).toBeGreaterThan(PRICING[m].input);
    }
  });

  it('cache_read is much cheaper than uncached input', () => {
    for (const m of [HAIKU, SONNET, OPUS] as const) {
      expect(PRICING[m].cacheRead).toBeLessThan(PRICING[m].input);
    }
  });
});

describe('estimateCostUsd', () => {
  it('charges Haiku $1/1M input + $5/1M output', () => {
    // 1,000,000 input + 1,000,000 output = $1 + $5 = $6
    expect(
      estimateCostUsd(HAIKU, { input_tokens: 1_000_000, output_tokens: 1_000_000 })
    ).toBe(6);
  });

  it('charges Sonnet $3/1M input + $15/1M output', () => {
    expect(
      estimateCostUsd(SONNET, { input_tokens: 1_000_000, output_tokens: 1_000_000 })
    ).toBe(18);
  });

  it('charges Opus $5/1M input + $25/1M output', () => {
    expect(
      estimateCostUsd(OPUS, { input_tokens: 1_000_000, output_tokens: 1_000_000 })
    ).toBe(30);
  });

  it('charges cache_read at the discounted rate', () => {
    // 1M cache_read at Haiku's $0.10 = $0.10
    const cost = estimateCostUsd(HAIKU, {
      input_tokens: 0,
      output_tokens: 0,
      cache_read_input_tokens: 1_000_000,
    });
    expect(cost).toBeCloseTo(0.1, 4);
  });

  it('charges cache_creation at the 1.25x premium', () => {
    // 1M cache_write at Haiku's $1.25 = $1.25
    const cost = estimateCostUsd(HAIKU, {
      input_tokens: 0,
      output_tokens: 0,
      cache_creation_input_tokens: 1_000_000,
    });
    expect(cost).toBeCloseTo(1.25, 4);
  });

  it('rounds to 4 decimals (matches DB column)', () => {
    const cost = estimateCostUsd(HAIKU, { input_tokens: 1, output_tokens: 1 });
    // 1 input @ $1/M = $0.000001 ≈ rounds to 0.0000
    expect(cost.toString().split('.')[1]?.length ?? 0).toBeLessThanOrEqual(4);
  });

  it('returns 0 for zero usage', () => {
    expect(
      estimateCostUsd(OPUS, { input_tokens: 0, output_tokens: 0 })
    ).toBe(0);
  });

  it('produces a realistic ticket-analysis cost for a typical Stage 1 call', () => {
    // ~10K input tokens, ~500 output tokens on Haiku ≈ $0.013
    const cost = estimateCostUsd(HAIKU, {
      input_tokens: 10_000,
      output_tokens: 500,
    });
    expect(cost).toBeCloseTo(0.0125, 4);
  });
});
