import { afterEach, beforeEach, describe, expect, it } from 'vitest';
import { MemoryDatastoreProvider } from '@bytelyst/datastore';
import { _resetDatastoreProvider, setProvider } from '../../lib/datastore.js';
import * as repo from './repository.js';

describe('ai budget repository', () => {
  beforeEach(() => {
    setProvider(new MemoryDatastoreProvider());
  });

  afterEach(() => {
    _resetDatastoreProvider();
  });

  it('stores policies, spend entries, and alerts', async () => {
    await repo.createPolicy({
      id: 'aibudget_1',
      productId: 'lysnrai',
      scopeType: 'agent',
      scopeId: 'agt_1',
      name: 'Incident Agent Budget',
      status: 'active',
      period: 'monthly',
      budgetUsd: 25,
      softThreshold: 0.8,
      hardThreshold: 1,
      modelAllowlist: ['gpt-4o-mini'],
      createdBy: 'admin_1',
      createdAt: '2026-03-15T00:00:00.000Z',
      updatedAt: '2026-03-15T00:00:00.000Z',
    });

    await repo.createSpendEntry({
      id: 'aispend_1',
      productId: 'lysnrai',
      policyId: 'aibudget_1',
      scopeType: 'agent',
      scopeId: 'agt_1',
      agentId: 'agt_1',
      agentVersionId: 'agt_1:v2',
      model: 'gpt-4o-mini',
      tokensUsed: 500,
      costUsd: 4.2,
      source: 'run',
      verdict: 'allow',
      recordedAt: '2026-03-15T00:10:00.000Z',
    });

    await repo.createAlerts([
      {
        id: 'aialert_1',
        productId: 'lysnrai',
        policyId: 'aibudget_1',
        scopeType: 'agent',
        scopeId: 'agt_1',
        severity: 'warn',
        message: 'Approaching budget',
        spendUsd: 20,
        budgetUsd: 25,
        percentUsed: 0.8,
        createdAt: '2026-03-15T00:11:00.000Z',
      },
    ]);

    const policies = await repo.listPolicies('lysnrai', { limit: 20 });
    const spend = await repo.listSpendEntries('lysnrai', { policyId: 'aibudget_1' });
    const alerts = await repo.listAlerts('lysnrai', { limit: 20 });

    expect(policies).toHaveLength(1);
    expect(spend[0].costUsd).toBe(4.2);
    expect(alerts[0].severity).toBe('warn');
  });
});
