import { UserDeactivatedListener } from '../listeners/user-deactivated.listener';

describe('UserDeactivatedListener', () => {
  let listener: UserDeactivatedListener;
  let mockPrisma: {
    listing: { updateMany: ReturnType<typeof vi.fn> };
  };
  let mockLogger: { log: ReturnType<typeof vi.fn>; warn: ReturnType<typeof vi.fn> };

  beforeEach(() => {
    mockPrisma = {
      listing: { updateMany: vi.fn().mockResolvedValue({ count: 5 }) },
    };
    mockLogger = { log: vi.fn(), warn: vi.fn() };

    listener = new UserDeactivatedListener(
      mockPrisma as any,
      mockLogger as any,
    );
  });

  it('expires ACTIVE and PENDING_REVIEW listings for deactivated user', async () => {
    await listener.handle({
      aggregateId: 'user-1',
      eventName: 'user.deactivated',
      occurredAt: new Date(),
    } as any);

    expect(mockPrisma.listing.updateMany).toHaveBeenCalledWith({
      where: {
        sellerId: 'user-1',
        status: { in: ['ACTIVE', 'PENDING_REVIEW'] },
      },
      data: { status: 'EXPIRED' },
    });
  });

  it('logs the deactivation handling', async () => {
    await listener.handle({
      aggregateId: 'user-42',
      eventName: 'user.deactivated',
      occurredAt: new Date(),
    } as any);

    expect(mockLogger.log).toHaveBeenCalledWith(
      expect.stringContaining('user-42'),
      'UserDeactivatedListener',
    );
  });

  it('logs the number of expired listings', async () => {
    mockPrisma.listing.updateMany.mockResolvedValue({ count: 3 });

    await listener.handle({
      aggregateId: 'user-1',
      eventName: 'user.deactivated',
      occurredAt: new Date(),
    } as any);

    expect(mockLogger.log).toHaveBeenCalledWith(
      expect.stringContaining('3'),
      'UserDeactivatedListener',
    );
  });

  it('handles user with no listings gracefully', async () => {
    mockPrisma.listing.updateMany.mockResolvedValue({ count: 0 });

    await listener.handle({
      aggregateId: 'user-no-listings',
      eventName: 'user.deactivated',
      occurredAt: new Date(),
    } as any);

    expect(mockPrisma.listing.updateMany).toHaveBeenCalled();
    expect(mockLogger.log).toHaveBeenCalledWith(
      expect.stringContaining('0'),
      'UserDeactivatedListener',
    );
  });
});
