import { RecordEngagementInputDTO } from './RecordEngagementInputDTO';
import { EngagementAction, EngagementEntityType } from '@core/analytics/domain/types/EngagementEvent';

describe('RecordEngagementInputDTO', () => {
  describe('TDD - Test First', () => {
    it('should create valid DTO with all fields', () => {
      // Arrange & Act
      const dto = new RecordEngagementInputDTO();
      dto.action = EngagementAction.CLICK_SPONSOR_LOGO;
      dto.entityType = EngagementEntityType.RACE;
      dto.entityId = 'race-123';
      dto.actorId = 'actor-456';
      dto.actorType = 'driver';
      dto.sessionId = 'session-789';
      dto.metadata = { key: 'value', count: 5 };

      // Assert
      expect(dto.action).toBe(EngagementAction.CLICK_SPONSOR_LOGO);
      expect(dto.entityType).toBe(EngagementEntityType.RACE);
      expect(dto.entityId).toBe('race-123');
      expect(dto.actorId).toBe('actor-456');
      expect(dto.actorType).toBe('driver');
      expect(dto.sessionId).toBe('session-789');
      expect(dto.metadata).toEqual({ key: 'value', count: 5 });
    });

    it('should create DTO with required fields only', () => {
      // Arrange & Act
      const dto = new RecordEngagementInputDTO();
      dto.action = EngagementAction.CLICK_SPONSOR_LOGO;
      dto.entityType = EngagementEntityType.RACE;
      dto.entityId = 'race-123';
      dto.actorType = 'anonymous';
      dto.sessionId = 'session-456';

      // Assert
      expect(dto.action).toBe(EngagementAction.CLICK_SPONSOR_LOGO);
      expect(dto.entityType).toBe(EngagementEntityType.RACE);
      expect(dto.entityId).toBe('race-123');
      expect(dto.actorType).toBe('anonymous');
      expect(dto.sessionId).toBe('session-456');
      expect(dto.actorId).toBeUndefined();
      expect(dto.metadata).toBeUndefined();
    });

    it('should handle CLICK_SPONSOR_LOGO action', () => {
      // Arrange & Act
      const dto = new RecordEngagementInputDTO();
      dto.action = EngagementAction.CLICK_SPONSOR_LOGO;
      dto.entityType = EngagementEntityType.RACE;
      dto.entityId = 'race-123';
      dto.actorType = 'anonymous';
      dto.sessionId = 'session-456';

      // Assert
      expect(dto.action).toBe(EngagementAction.CLICK_SPONSOR_LOGO);
    });

    it('should handle CLICK_SPONSOR_URL action', () => {
      // Arrange & Act
      const dto = new RecordEngagementInputDTO();
      dto.action = EngagementAction.CLICK_SPONSOR_URL;
      dto.entityType = EngagementEntityType.RACE;
      dto.entityId = 'race-123';
      dto.actorType = 'anonymous';
      dto.sessionId = 'session-456';

      // Assert
      expect(dto.action).toBe(EngagementAction.CLICK_SPONSOR_URL);
    });

    it('should handle RACE entity type', () => {
      // Arrange & Act
      const dto = new RecordEngagementInputDTO();
      dto.action = EngagementAction.CLICK_SPONSOR_LOGO;
      dto.entityType = EngagementEntityType.RACE;
      dto.entityId = 'race-123';
      dto.actorType = 'anonymous';
      dto.sessionId = 'session-456';

      // Assert
      expect(dto.entityType).toBe(EngagementEntityType.RACE);
    });

    it('should handle LEAGUE entity type', () => {
      // Arrange & Act
      const dto = new RecordEngagementInputDTO();
      dto.action = EngagementAction.CLICK_SPONSOR_LOGO;
      dto.entityType = EngagementEntityType.LEAGUE;
      dto.entityId = 'league-123';
      dto.actorType = 'anonymous';
      dto.sessionId = 'session-456';

      // Assert
      expect(dto.entityType).toBe(EngagementEntityType.LEAGUE);
    });

    it('should handle DRIVER entity type', () => {
      // Arrange & Act
      const dto = new RecordEngagementInputDTO();
      dto.action = EngagementAction.CLICK_SPONSOR_LOGO;
      dto.entityType = EngagementEntityType.DRIVER;
      dto.entityId = 'driver-123';
      dto.actorType = 'anonymous';
      dto.sessionId = 'session-456';

      // Assert
      expect(dto.entityType).toBe(EngagementEntityType.DRIVER);
    });

    it('should handle TEAM entity type', () => {
      // Arrange & Act
      const dto = new RecordEngagementInputDTO();
      dto.action = EngagementAction.CLICK_SPONSOR_LOGO;
      dto.entityType = EngagementEntityType.TEAM;
      dto.entityId = 'team-123';
      dto.actorType = 'anonymous';
      dto.sessionId = 'session-456';

      // Assert
      expect(dto.entityType).toBe(EngagementEntityType.TEAM);
    });

    it('should handle anonymous actor type', () => {
      // Arrange & Act
      const dto = new RecordEngagementInputDTO();
      dto.action = EngagementAction.CLICK_SPONSOR_LOGO;
      dto.entityType = EngagementEntityType.RACE;
      dto.entityId = 'race-123';
      dto.actorType = 'anonymous';
      dto.sessionId = 'session-456';

      // Assert
      expect(dto.actorType).toBe('anonymous');
    });

    it('should handle driver actor type', () => {
      // Arrange & Act
      const dto = new RecordEngagementInputDTO();
      dto.action = EngagementAction.CLICK_SPONSOR_LOGO;
      dto.entityType = EngagementEntityType.RACE;
      dto.entityId = 'race-123';
      dto.actorType = 'driver';
      dto.sessionId = 'session-456';

      // Assert
      expect(dto.actorType).toBe('driver');
    });

    it('should handle sponsor actor type', () => {
      // Arrange & Act
      const dto = new RecordEngagementInputDTO();
      dto.action = EngagementAction.CLICK_SPONSOR_LOGO;
      dto.entityType = EngagementEntityType.RACE;
      dto.entityId = 'race-123';
      dto.actorType = 'sponsor';
      dto.sessionId = 'session-456';

      // Assert
      expect(dto.actorType).toBe('sponsor');
    });

    it('should handle empty metadata', () => {
      // Arrange & Act
      const dto = new RecordEngagementInputDTO();
      dto.action = EngagementAction.CLICK_SPONSOR_LOGO;
      dto.entityType = EngagementEntityType.RACE;
      dto.entityId = 'race-123';
      dto.actorType = 'anonymous';
      dto.sessionId = 'session-456';
      dto.metadata = {};

      // Assert
      expect(dto.metadata).toEqual({});
    });

    it('should handle metadata with multiple keys', () => {
      // Arrange & Act
      const dto = new RecordEngagementInputDTO();
      dto.action = EngagementAction.CLICK_SPONSOR_LOGO;
      dto.entityType = EngagementEntityType.RACE;
      dto.entityId = 'race-123';
      dto.actorType = 'anonymous';
      dto.sessionId = 'session-456';
      dto.metadata = {
        key1: 'value1',
        key2: 'value2',
        key3: 'value3',
      };

      // Assert
      expect(dto.metadata).toEqual({
        key1: 'value1',
        key2: 'value2',
        key3: 'value3',
      });
    });

    it('should handle metadata with numeric values', () => {
      // Arrange & Act
      const dto = new RecordEngagementInputDTO();
      dto.action = EngagementAction.CLICK_SPONSOR_LOGO;
      dto.entityType = EngagementEntityType.RACE;
      dto.entityId = 'race-123';
      dto.actorType = 'anonymous';
      dto.sessionId = 'session-456';
      dto.metadata = { count: 10, score: 95.5 };

      // Assert
      expect(dto.metadata).toEqual({ count: 10, score: 95.5 });
    });

    it('should handle metadata with boolean values', () => {
      // Arrange & Act
      const dto = new RecordEngagementInputDTO();
      dto.action = EngagementAction.CLICK_SPONSOR_LOGO;
      dto.entityType = EngagementEntityType.RACE;
      dto.entityId = 'race-123';
      dto.actorType = 'anonymous';
      dto.sessionId = 'session-456';
      dto.metadata = { isFeatured: true, isPremium: false };

      // Assert
      expect(dto.metadata).toEqual({ isFeatured: true, isPremium: false });
    });

    it('should handle very long entity ID', () => {
      // Arrange
      const longId = 'a'.repeat(100);

      // Act
      const dto = new RecordEngagementInputDTO();
      dto.action = EngagementAction.CLICK_SPONSOR_LOGO;
      dto.entityType = EngagementEntityType.RACE;
      dto.entityId = longId;
      dto.actorType = 'anonymous';
      dto.sessionId = 'session-456';

      // Assert
      expect(dto.entityId).toBe(longId);
    });

    it('should handle very long session ID', () => {
      // Arrange
      const longSessionId = 's'.repeat(100);

      // Act
      const dto = new RecordEngagementInputDTO();
      dto.action = EngagementAction.CLICK_SPONSOR_LOGO;
      dto.entityType = EngagementEntityType.RACE;
      dto.entityId = 'race-123';
      dto.actorType = 'anonymous';
      dto.sessionId = longSessionId;

      // Assert
      expect(dto.sessionId).toBe(longSessionId);
    });

    it('should handle very long actor ID', () => {
      // Arrange
      const longActorId = 'a'.repeat(100);

      // Act
      const dto = new RecordEngagementInputDTO();
      dto.action = EngagementAction.CLICK_SPONSOR_LOGO;
      dto.entityType = EngagementEntityType.RACE;
      dto.entityId = 'race-123';
      dto.actorType = 'driver';
      dto.sessionId = 'session-456';
      dto.actorId = longActorId;

      // Assert
      expect(dto.actorId).toBe(longActorId);
    });

    it('should handle special characters in entity ID', () => {
      // Arrange & Act
      const dto = new RecordEngagementInputDTO();
      dto.action = EngagementAction.CLICK_SPONSOR_LOGO;
      dto.entityType = EngagementEntityType.RACE;
      dto.entityId = 'race-123-test-456';
      dto.actorType = 'anonymous';
      dto.sessionId = 'session-789';

      // Assert
      expect(dto.entityId).toBe('race-123-test-456');
    });

    it('should handle UUID format for entity ID', () => {
      // Arrange
      const uuid = '550e8400-e29b-41d4-a716-446655440000';

      // Act
      const dto = new RecordEngagementInputDTO();
      dto.action = EngagementAction.CLICK_SPONSOR_LOGO;
      dto.entityType = EngagementEntityType.RACE;
      dto.entityId = uuid;
      dto.actorType = 'anonymous';
      dto.sessionId = 'session-456';

      // Assert
      expect(dto.entityId).toBe(uuid);
    });

    it('should handle numeric entity ID', () => {
      // Arrange & Act
      const dto = new RecordEngagementInputDTO();
      dto.action = EngagementAction.CLICK_SPONSOR_LOGO;
      dto.entityType = EngagementEntityType.RACE;
      dto.entityId = '123456';
      dto.actorType = 'anonymous';
      dto.sessionId = 'session-456';

      // Assert
      expect(dto.entityId).toBe('123456');
    });

    it('should handle complex metadata with string values', () => {
      // Arrange & Act
      const dto = new RecordEngagementInputDTO();
      dto.action = EngagementAction.CLICK_SPONSOR_LOGO;
      dto.entityType = EngagementEntityType.RACE;
      dto.entityId = 'race-123';
      dto.actorType = 'anonymous';
      dto.sessionId = 'session-456';
      dto.metadata = {
        position: '100,200',
        timestamp: '2024-01-01T00:00:00Z',
        isValid: 'true',
      };

      // Assert
      expect(dto.metadata).toEqual({
        position: '100,200',
        timestamp: '2024-01-01T00:00:00Z',
        isValid: 'true',
      });
    });
  });
});
