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

import { describe, it, expect, beforeEach, afterAll } from 'vitest';
import { MemoryDatastoreProvider } from '@bytelyst/datastore';
import { setProvider, _resetDatastoreProvider } from '../../lib/datastore.js';
import { list, getByName, create, update, getDefaults } from './repository.js';
import type { PlanConfig } from './types.js';

const basePlan: PlanConfig = {
  id: 'plan_lysnrai_pro',
  productId: 'lysnrai',
  name: 'pro',
  displayName: 'Pro',
  price: 9.99,
  tokens: 100000,
  words: 50000,
  dictations: 5000,
  features: ['basic_dictation', 'all_languages'],
  active: true,
  createdAt: '2026-02-16T00:00:00Z',
  updatedAt: '2026-02-16T00:00:00Z',
};

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

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

  describe('list', () => {
    it('returns plans from datastore', async () => {
      await create(basePlan);
      const result = await list('lysnrai');
      expect(result).toHaveLength(1);
      expect(result[0]!.name).toBe('pro');
    });

    it('returns defaults when no plans in DB', async () => {
      const result = await list('lysnrai');
      expect(result).toHaveLength(3);
      expect(result[0].name).toBe('free');
      expect(result[1].name).toBe('pro');
      expect(result[2].name).toBe('enterprise');
    });
  });

  describe('getByName', () => {
    it('returns plan when found', async () => {
      await create(basePlan);
      const result = await getByName('pro', 'lysnrai');
      expect(result).toEqual(basePlan);
    });

    it('returns null when not found', async () => {
      const result = await getByName('nonexistent', 'lysnrai');
      expect(result).toBeNull();
    });
  });

  describe('create', () => {
    it('creates and returns plan', async () => {
      const result = await create(basePlan);
      expect(result).toEqual(basePlan);
    });
  });

  describe('update', () => {
    it('merges updates and returns plan', async () => {
      await create(basePlan);
      const result = await update('plan_lysnrai_pro', { price: 14.99 });
      expect(result).not.toBeNull();
      expect(result!.price).toBe(14.99);
    });

    it('returns null when plan not found', async () => {
      const result = await update('nonexistent', { price: 14.99 });
      expect(result).toBeNull();
    });
  });

  describe('getDefaults', () => {
    it('returns 3 default plans with correct productId', () => {
      const defaults = getDefaults('lysnrai');
      expect(defaults).toHaveLength(3);
      expect(defaults.every(p => p.productId === 'lysnrai')).toBe(true);
      expect(defaults[0].name).toBe('free');
      expect(defaults[0].price).toBe(0);
      expect(defaults[1].name).toBe('pro');
      expect(defaults[2].name).toBe('enterprise');
    });

    it('generates correct IDs', () => {
      const defaults = getDefaults('mindlyst');
      expect(defaults[0].id).toBe('plan_mindlyst_free');
      expect(defaults[1].id).toBe('plan_mindlyst_pro');
    });
  });
});
