import { beforeEach, describe, expect, it, vi } from 'vitest';
import type { Logger } from '@core/shared/application';
import { Notification } from '@core/notifications/domain/entities/Notification';
import { InMemoryNotificationRepository } from './InMemoryNotificationRepository';

describe('InMemoryNotificationRepository', () => {
  let repository: InMemoryNotificationRepository;
  let logger: Logger;

  beforeEach(() => {
    logger = {
      debug: vi.fn(),
      info: vi.fn(),
      warn: vi.fn(),
      error: vi.fn(),
    } as unknown as Logger;

    repository = new InMemoryNotificationRepository(logger);
  });

  it('creates, finds, counts and marks as read', async () => {
    const n1 = Notification.create({
      id: 'n1',
      recipientId: 'driver-1',
      type: 'system_announcement',
      title: 'T1',
      body: 'B1',
      channel: 'in_app',
      status: 'unread',
    });
    const n2 = Notification.create({
      id: 'n2',
      recipientId: 'driver-1',
      type: 'system_announcement',
      title: 'T2',
      body: 'B2',
      channel: 'in_app',
      status: 'unread',
    });
    const n3 = Notification.create({
      id: 'n3',
      recipientId: 'driver-2',
      type: 'system_announcement',
      title: 'T3',
      body: 'B3',
      channel: 'in_app',
      status: 'unread',
    });

    await repository.create(n1);
    await repository.create(n2);
    await repository.create(n3);

    expect((await repository.findById('n1'))?.id).toBe('n1');
    expect((await repository.findByRecipientId('driver-1')).length).toBe(2);
    expect(await repository.countUnreadByRecipientId('driver-1')).toBe(2);

    await repository.markAllAsReadByRecipientId('driver-1');
    expect(await repository.countUnreadByRecipientId('driver-1')).toBe(0);

    const unread = await repository.findUnreadByRecipientId('driver-1');
    expect(unread).toEqual([]);
  });

  it('deletes all by recipient', async () => {
    const n = Notification.create({
      id: 'n-del',
      recipientId: 'driver-del',
      type: 'system_announcement',
      title: 'T',
      body: 'B',
      channel: 'in_app',
    });

    await repository.create(n);
    await repository.deleteAllByRecipientId('driver-del');

    expect(await repository.findById('n-del')).toBeNull();
  });
});
