/**
 * Event Publisher Service Integration Tests
 */

import { Test, TestingModule } from '@nestjs/testing';
import { EventPublisherService } from '../../src/infrastructure/messaging/kafka/event-publisher.service';
import { ConfigService } from '@nestjs/config';
import {
  ShareCreatedEvent,
  ShareRotatedEvent,
  ShareRevokedEvent,
  KeygenCompletedEvent,
  SigningCompletedEvent,
  SessionFailedEvent,
} from '../../src/domain/events';
import { PartyShareType, SessionType } from '../../src/domain/enums';

describe('EventPublisherService (Integration)', () => {
  let service: EventPublisherService;
  let mockConfigService: any;

  beforeEach(async () => {
    mockConfigService = {
      get: jest.fn((key: string, defaultValue?: any) => {
        const config: Record<string, any> = {
          'kafka.brokers': ['localhost:9092'],
          'kafka.clientId': 'mpc-party-service',
          KAFKA_ENABLED: 'false', // Disable for tests
        };
        return config[key] ?? defaultValue;
      }),
    };

    const module: TestingModule = await Test.createTestingModule({
      providers: [
        EventPublisherService,
        { provide: ConfigService, useValue: mockConfigService },
      ],
    }).compile();

    service = module.get<EventPublisherService>(EventPublisherService);
  });

  it('should be defined', () => {
    expect(service).toBeDefined();
  });

  describe('event creation', () => {
    it('should create ShareCreatedEvent', () => {
      const event = new ShareCreatedEvent(
        'share-123',
        'user123-server',
        '550e8400-e29b-41d4-a716-446655440000',
        PartyShareType.WALLET,
        '03' + '0'.repeat(64),
        '2-of-3',
      );

      expect(event.eventType).toBe('ShareCreated');
      expect(event.aggregateId).toBe('share-123');
      expect(event.aggregateType).toBe('PartyShare');
      expect(event.payload).toHaveProperty('shareId', 'share-123');
      expect(event.payload).toHaveProperty('partyId', 'user123-server');
      expect(event.payload).toHaveProperty('shareType', PartyShareType.WALLET);
    });

    it('should create ShareRotatedEvent', () => {
      const event = new ShareRotatedEvent(
        'new-share-456',
        'old-share-123',
        'user123-server',
        '660e8400-e29b-41d4-a716-446655440001',
      );

      expect(event.eventType).toBe('ShareRotated');
      expect(event.aggregateId).toBe('new-share-456');
      expect(event.payload).toHaveProperty('newShareId', 'new-share-456');
      expect(event.payload).toHaveProperty('oldShareId', 'old-share-123');
    });

    it('should create ShareRevokedEvent', () => {
      const event = new ShareRevokedEvent(
        'share-123',
        'user123-server',
        'Security concern',
      );

      expect(event.eventType).toBe('ShareRevoked');
      expect(event.aggregateId).toBe('share-123');
      expect(event.payload).toHaveProperty('reason', 'Security concern');
    });

    it('should create KeygenCompletedEvent', () => {
      const event = new KeygenCompletedEvent(
        '550e8400-e29b-41d4-a716-446655440000',
        'user123-server',
        '03' + '0'.repeat(64),
        'share-123',
        '2-of-3',
      );

      expect(event.eventType).toBe('KeygenCompleted');
      expect(event.aggregateId).toBe('550e8400-e29b-41d4-a716-446655440000');
      expect(event.aggregateType).toBe('PartySession');
    });

    it('should create SigningCompletedEvent', () => {
      const event = new SigningCompletedEvent(
        '550e8400-e29b-41d4-a716-446655440000',
        'user123-server',
        'a'.repeat(64),
        'signature-hex',
        '03' + '0'.repeat(64),
      );

      expect(event.eventType).toBe('SigningCompleted');
      expect(event.aggregateType).toBe('PartySession');
      expect(event.payload).toHaveProperty('messageHash', 'a'.repeat(64));
    });

    it('should create SessionFailedEvent', () => {
      const event = new SessionFailedEvent(
        '550e8400-e29b-41d4-a716-446655440000',
        'user123-server',
        SessionType.KEYGEN,
        'Protocol error',
        'ERR_PROTOCOL',
      );

      expect(event.eventType).toBe('SessionFailed');
      expect(event.payload).toHaveProperty('sessionType', SessionType.KEYGEN);
      expect(event.payload).toHaveProperty('errorMessage', 'Protocol error');
      expect(event.payload).toHaveProperty('errorCode', 'ERR_PROTOCOL');
    });
  });

  describe('event metadata', () => {
    it('should have eventId and occurredAt', () => {
      const event = new ShareCreatedEvent(
        'share-123',
        'user123-server',
        '550e8400-e29b-41d4-a716-446655440000',
        PartyShareType.WALLET,
        '03' + '0'.repeat(64),
        '2-of-3',
      );

      expect(event.eventId).toBeDefined();
      expect(event.eventId).toMatch(/^[0-9a-f-]+$/i);
      expect(event.occurredAt).toBeInstanceOf(Date);
    });

    it('should generate unique event IDs', () => {
      const event1 = new ShareCreatedEvent(
        'share-1',
        'user123-server',
        '550e8400-e29b-41d4-a716-446655440000',
        PartyShareType.WALLET,
        'pk1',
        '2-of-3',
      );
      const event2 = new ShareCreatedEvent(
        'share-2',
        'user123-server',
        '550e8400-e29b-41d4-a716-446655440001',
        PartyShareType.WALLET,
        'pk2',
        '2-of-3',
      );

      expect(event1.eventId).not.toBe(event2.eventId);
    });
  });

  describe('publish', () => {
    it('should have publish method', () => {
      expect(typeof service.publish).toBe('function');
    });

    it('should have publishAll method', () => {
      expect(typeof service.publishAll).toBe('function');
    });
  });
});
