/**
 * Repository tests for usage module — in-memory datastore.
 */

import { describe, it, expect, beforeEach } from 'vitest';
import { MemoryDatastoreProvider } from '@bytelyst/datastore';
import { setProvider } from '../../lib/datastore.js';
import { getByDate, list, upsert, getMonthlyUsage } from './repository.js';
import type { UsageDoc } from './types.js';

// Use today's date so getMonthlyUsage picks it up
const todayStr = new Date().toISOString().slice(0, 10);

const baseUsage: UsageDoc = {
  id: `usg_${todayStr}_user_1`,
  productId: 'lysnrai',
  userId: 'user_1',
  date: todayStr,
  dictations: 5,
  words: 250,
  durationMs: 30000,
  tokensUsed: 1200,
  costUsd: 0.01,
  createdAt: `${todayStr}T00:00:00Z`,
};

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

  describe('getByDate', () => {
    it('returns usage when found', async () => {
      await upsert(baseUsage);
      const result = await getByDate('user_1', todayStr);
      expect(result).not.toBeNull();
      expect(result!.dictations).toBe(5);
    });

    it('returns null when not found', async () => {
      const result = await getByDate('user_1', '2026-02-16');
      expect(result).toBeNull();
    });
  });

  describe('list', () => {
    it('returns usage records', async () => {
      await upsert(baseUsage);
      const result = await list({ userId: 'user_1', productId: 'lysnrai' });
      expect(result).toHaveLength(1);
      expect(result[0].userId).toBe('user_1');
    });

    it('returns empty array when no records', async () => {
      const result = await list({});
      expect(result).toEqual([]);
    });

    it('uses default values for days and limit', async () => {
      const result = await list();
      expect(result).toEqual([]);
    });
  });

  describe('upsert', () => {
    it('upserts and returns usage', async () => {
      const result = await upsert(baseUsage);
      expect(result.id).toBe(baseUsage.id);
      expect(result.words).toBe(250);
    });
  });

  describe('getMonthlyUsage', () => {
    it('returns aggregated monthly usage', async () => {
      await upsert(baseUsage);
      const result = await getMonthlyUsage('user_1', 'lysnrai');
      expect(result).toEqual({ tokens: 1200, words: 250, dictations: 5 });
    });

    it('returns zeros when no data', async () => {
      const result = await getMonthlyUsage('user_1', 'lysnrai');
      expect(result).toEqual({ tokens: 0, words: 0, dictations: 0 });
    });

    it('returns zeros when empty resources', async () => {
      const result = await getMonthlyUsage('nonexistent', 'lysnrai');
      expect(result).toEqual({ tokens: 0, words: 0, dictations: 0 });
    });
  });
});
