import { ListingSoldListener } from '../listeners/listing-sold.listener';

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

  beforeEach(() => {
    mockCommandBus = { execute: vi.fn().mockResolvedValue(undefined) };
    mockPrisma = {
      listing: { findUnique: vi.fn() },
    };
    mockLogger = { log: vi.fn(), warn: vi.fn() };

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

  it('notifies seller when listing is sold', async () => {
    mockPrisma.listing.findUnique.mockResolvedValue({
      id: 'listing-1',
      property: { title: 'Căn hộ đẹp' },
      seller: { id: 'seller-1', email: 'seller@example.com' },
    });

    await listener.handle({
      aggregateId: 'listing-1',
      propertyId: 'prop-1',
      finalStatus: 'SOLD',
      eventName: 'listing.sold',
      occurredAt: new Date(),
    });

    expect(mockCommandBus.execute).toHaveBeenCalledWith(
      expect.objectContaining({
        userId: 'seller-1',
        channel: 'EMAIL',
        templateKey: 'listing.sold',
      }),
    );
  });

  it('notifies only seller when listing is sold (no watcher support)', async () => {
    mockPrisma.listing.findUnique.mockResolvedValue({
      id: 'listing-1',
      property: { title: 'Căn hộ đẹp' },
      seller: { id: 'seller-1', email: 'seller@example.com' },
    });

    await listener.handle({
      aggregateId: 'listing-1',
      propertyId: 'prop-1',
      finalStatus: 'SOLD',
      eventName: 'listing.sold',
      occurredAt: new Date(),
    });

    // Only seller notification (savedListing model removed)
    expect(mockCommandBus.execute).toHaveBeenCalledTimes(1);
  });

  it('skips notification when listing not found', async () => {
    mockPrisma.listing.findUnique.mockResolvedValue(null);

    await listener.handle({
      aggregateId: 'nonexistent',
      propertyId: 'prop-1',
      finalStatus: 'SOLD',
      eventName: 'listing.sold',
      occurredAt: new Date(),
    });

    expect(mockCommandBus.execute).not.toHaveBeenCalled();
  });
});
