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

import { describe, it, expect, beforeEach } from 'vitest';
import { MemoryDatastoreProvider } from '@bytelyst/datastore';
import { setProvider } from '../../lib/datastore.js';
import {
  getDevicesByUser,
  upsertDevice,
  removeDevice,
  getPrefs,
  upsertPrefs,
} from './repository.js';
import type { DeviceDoc, NotificationPrefsDoc } from './types.js';

const baseDevice: DeviceDoc = {
  id: 'dev_1',
  productId: 'lysnrai',
  userId: 'user_1',
  deviceId: 'device_abc',
  platform: 'ios',
  pushToken: 'token_xyz',
  lastSeenAt: '2026-02-16T00:00:00Z',
  createdAt: '2026-02-16T00:00:00Z',
  updatedAt: '2026-02-16T00:00:00Z',
};

const basePrefs: NotificationPrefsDoc = {
  id: 'prefs_lysnrai_user_1',
  productId: 'lysnrai',
  userId: 'user_1',
  pushEnabled: true,
  emailEnabled: false,
  categories: { marketing: false, updates: true },
  createdAt: '2026-02-16T00:00:00Z',
  updatedAt: '2026-02-16T00:00:00Z',
};

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

  describe('getDevicesByUser', () => {
    it('returns devices for user', async () => {
      await upsertDevice(baseDevice);
      const result = await getDevicesByUser('user_1', 'lysnrai');
      expect(result).toHaveLength(1);
      expect(result[0].id).toBe('dev_1');
    });

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

  describe('upsertDevice', () => {
    it('upserts and returns device', async () => {
      const result = await upsertDevice(baseDevice);
      expect(result.id).toBe('dev_1');
      expect(result.platform).toBe('ios');
    });
  });

  describe('removeDevice', () => {
    it('returns true on successful delete', async () => {
      await upsertDevice(baseDevice);
      const result = await removeDevice('dev_1', 'user_1');
      expect(result).toBe(true);
    });
  });

  describe('getPrefs', () => {
    it('returns prefs when found', async () => {
      await upsertPrefs(basePrefs);
      const result = await getPrefs('user_1', 'lysnrai');
      expect(result).not.toBeNull();
      expect(result!.pushEnabled).toBe(true);
    });

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

  describe('upsertPrefs', () => {
    it('upserts and returns prefs', async () => {
      const result = await upsertPrefs(basePrefs);
      expect(result.id).toBe('prefs_lysnrai_user_1');
      expect(result.pushEnabled).toBe(true);
    });
  });
});
