import { RecordPageViewInputDTO } from './RecordPageViewInputDTO';
import { EntityType, VisitorType } from '@core/analytics/domain/types/PageView';

describe('RecordPageViewInputDTO', () => {
  describe('TDD - Test First', () => {
    it('should create valid DTO with all fields', () => {
      // Arrange & Act
      const dto = new RecordPageViewInputDTO();
      dto.entityType = EntityType.RACE;
      dto.entityId = 'race-123';
      dto.visitorId = 'visitor-456';
      dto.visitorType = VisitorType.ANONYMOUS;
      dto.sessionId = 'session-789';
      dto.referrer = 'https://example.com';
      dto.userAgent = 'Mozilla/5.0';
      dto.country = 'US';

      // Assert
      expect(dto.entityType).toBe(EntityType.RACE);
      expect(dto.entityId).toBe('race-123');
      expect(dto.visitorId).toBe('visitor-456');
      expect(dto.visitorType).toBe(VisitorType.ANONYMOUS);
      expect(dto.sessionId).toBe('session-789');
      expect(dto.referrer).toBe('https://example.com');
      expect(dto.userAgent).toBe('Mozilla/5.0');
      expect(dto.country).toBe('US');
    });

    it('should create DTO with required fields only', () => {
      // Arrange & Act
      const dto = new RecordPageViewInputDTO();
      dto.entityType = EntityType.LEAGUE;
      dto.entityId = 'league-123';
      dto.visitorType = VisitorType.AUTHENTICATED;
      dto.sessionId = 'session-456';

      // Assert
      expect(dto.entityType).toBe(EntityType.LEAGUE);
      expect(dto.entityId).toBe('league-123');
      expect(dto.visitorType).toBe(VisitorType.AUTHENTICATED);
      expect(dto.sessionId).toBe('session-456');
      expect(dto.visitorId).toBeUndefined();
      expect(dto.referrer).toBeUndefined();
      expect(dto.userAgent).toBeUndefined();
      expect(dto.country).toBeUndefined();
    });

    it('should handle RACE entity type', () => {
      // Arrange & Act
      const dto = new RecordPageViewInputDTO();
      dto.entityType = EntityType.RACE;
      dto.entityId = 'race-123';
      dto.visitorType = VisitorType.ANONYMOUS;
      dto.sessionId = 'session-456';

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

    it('should handle LEAGUE entity type', () => {
      // Arrange & Act
      const dto = new RecordPageViewInputDTO();
      dto.entityType = EntityType.LEAGUE;
      dto.entityId = 'league-123';
      dto.visitorType = VisitorType.ANONYMOUS;
      dto.sessionId = 'session-456';

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

    it('should handle DRIVER entity type', () => {
      // Arrange & Act
      const dto = new RecordPageViewInputDTO();
      dto.entityType = EntityType.DRIVER;
      dto.entityId = 'driver-123';
      dto.visitorType = VisitorType.ANONYMOUS;
      dto.sessionId = 'session-456';

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

    it('should handle TEAM entity type', () => {
      // Arrange & Act
      const dto = new RecordPageViewInputDTO();
      dto.entityType = EntityType.TEAM;
      dto.entityId = 'team-123';
      dto.visitorType = VisitorType.ANONYMOUS;
      dto.sessionId = 'session-456';

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

    it('should handle ANONYMOUS visitor type', () => {
      // Arrange & Act
      const dto = new RecordPageViewInputDTO();
      dto.entityType = EntityType.RACE;
      dto.entityId = 'race-123';
      dto.visitorType = VisitorType.ANONYMOUS;
      dto.sessionId = 'session-456';

      // Assert
      expect(dto.visitorType).toBe(VisitorType.ANONYMOUS);
    });

    it('should handle AUTHENTICATED visitor type', () => {
      // Arrange & Act
      const dto = new RecordPageViewInputDTO();
      dto.entityType = EntityType.RACE;
      dto.entityId = 'race-123';
      dto.visitorType = VisitorType.AUTHENTICATED;
      dto.sessionId = 'session-456';

      // Assert
      expect(dto.visitorType).toBe(VisitorType.AUTHENTICATED);
    });

    it('should handle empty referrer', () => {
      // Arrange & Act
      const dto = new RecordPageViewInputDTO();
      dto.entityType = EntityType.RACE;
      dto.entityId = 'race-123';
      dto.visitorType = VisitorType.ANONYMOUS;
      dto.sessionId = 'session-456';
      dto.referrer = '';

      // Assert
      expect(dto.referrer).toBe('');
    });

    it('should handle empty userAgent', () => {
      // Arrange & Act
      const dto = new RecordPageViewInputDTO();
      dto.entityType = EntityType.RACE;
      dto.entityId = 'race-123';
      dto.visitorType = VisitorType.ANONYMOUS;
      dto.sessionId = 'session-456';
      dto.userAgent = '';

      // Assert
      expect(dto.userAgent).toBe('');
    });

    it('should handle empty country', () => {
      // Arrange & Act
      const dto = new RecordPageViewInputDTO();
      dto.entityType = EntityType.RACE;
      dto.entityId = 'race-123';
      dto.visitorType = VisitorType.ANONYMOUS;
      dto.sessionId = 'session-456';
      dto.country = '';

      // Assert
      expect(dto.country).toBe('');
    });

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

      // Act
      const dto = new RecordPageViewInputDTO();
      dto.entityType = EntityType.RACE;
      dto.entityId = longId;
      dto.visitorType = VisitorType.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 RecordPageViewInputDTO();
      dto.entityType = EntityType.RACE;
      dto.entityId = 'race-123';
      dto.visitorType = VisitorType.ANONYMOUS;
      dto.sessionId = longSessionId;

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

    it('should handle very long visitor ID', () => {
      // Arrange
      const longVisitorId = 'v'.repeat(100);

      // Act
      const dto = new RecordPageViewInputDTO();
      dto.entityType = EntityType.RACE;
      dto.entityId = 'race-123';
      dto.visitorType = VisitorType.AUTHENTICATED;
      dto.sessionId = 'session-456';
      dto.visitorId = longVisitorId;

      // Assert
      expect(dto.visitorId).toBe(longVisitorId);
    });

    it('should handle special characters in entity ID', () => {
      // Arrange & Act
      const dto = new RecordPageViewInputDTO();
      dto.entityType = EntityType.RACE;
      dto.entityId = 'race-123-test-456';
      dto.visitorType = VisitorType.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 RecordPageViewInputDTO();
      dto.entityType = EntityType.RACE;
      dto.entityId = uuid;
      dto.visitorType = VisitorType.ANONYMOUS;
      dto.sessionId = 'session-456';

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

    it('should handle numeric entity ID', () => {
      // Arrange & Act
      const dto = new RecordPageViewInputDTO();
      dto.entityType = EntityType.RACE;
      dto.entityId = '123456';
      dto.visitorType = VisitorType.ANONYMOUS;
      dto.sessionId = 'session-456';

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

    it('should handle URL in referrer', () => {
      // Arrange & Act
      const dto = new RecordPageViewInputDTO();
      dto.entityType = EntityType.RACE;
      dto.entityId = 'race-123';
      dto.visitorType = VisitorType.ANONYMOUS;
      dto.sessionId = 'session-456';
      dto.referrer = 'https://www.example.com/path/to/page?query=value';

      // Assert
      expect(dto.referrer).toBe('https://www.example.com/path/to/page?query=value');
    });

    it('should handle complex user agent string', () => {
      // Arrange & Act
      const dto = new RecordPageViewInputDTO();
      dto.entityType = EntityType.RACE;
      dto.entityId = 'race-123';
      dto.visitorType = VisitorType.ANONYMOUS;
      dto.sessionId = 'session-456';
      dto.userAgent =
        'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36';

      // Assert
      expect(dto.userAgent).toBe(
        'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
      );
    });

    it('should handle country codes', () => {
      // Arrange & Act
      const dto = new RecordPageViewInputDTO();
      dto.entityType = EntityType.RACE;
      dto.entityId = 'race-123';
      dto.visitorType = VisitorType.ANONYMOUS;
      dto.sessionId = 'session-456';
      dto.country = 'GB';

      // Assert
      expect(dto.country).toBe('GB');
    });

    it('should handle country with region', () => {
      // Arrange & Act
      const dto = new RecordPageViewInputDTO();
      dto.entityType = EntityType.RACE;
      dto.entityId = 'race-123';
      dto.visitorType = VisitorType.ANONYMOUS;
      dto.sessionId = 'session-456';
      dto.country = 'US-CA';

      // Assert
      expect(dto.country).toBe('US-CA');
    });
  });
});
