/**
 * Repository tests for products 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 { getAll, getById, create, update } from './repository.js';
import type { ProductDoc } from './types.js';

const baseProduct: ProductDoc = {
  id: 'lysnrai',
  productId: 'lysnrai',
  displayName: 'LysnrAI',
  licensePrefix: 'LYSNR',
  packageName: 'com.bytelyst.lysnrai',
  defaultPlan: 'free',
  trialDays: 14,
  deviceLimits: { free: 1, pro: 3, enterprise: 10 },
  websiteUrl: 'https://lysnr.ai',
  status: 'active',
  createdAt: '2026-02-16T00:00:00Z',
  updatedAt: '2026-02-16T00:00:00Z',
};

let memProvider: MemoryDatastoreProvider;

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

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

  describe('getAll', () => {
    it('returns all products', async () => {
      await create(baseProduct);
      const result = await getAll();
      expect(result).toHaveLength(1);
      expect(result[0]!.id).toBe('lysnrai');
    });

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

  describe('getById', () => {
    it('returns product when found', async () => {
      await create(baseProduct);
      const result = await getById('lysnrai');
      expect(result).toEqual(baseProduct);
    });

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

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

  describe('update', () => {
    it('merges updates and returns product', async () => {
      await create(baseProduct);
      const result = await update('lysnrai', { displayName: 'LysnrAI Pro' });
      expect(result).not.toBeNull();
      expect(result!.displayName).toBe('LysnrAI Pro');
      expect(result!.id).toBe('lysnrai');
    });

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