import { TeamRatingEvent } from '@core/racing/domain/entities/TeamRatingEvent';
import { TeamRatingDelta } from '@core/racing/domain/value-objects/TeamRatingDelta';
import { TeamRatingDimensionKey } from '@core/racing/domain/value-objects/TeamRatingDimensionKey';
import { TeamRatingEventId } from '@core/racing/domain/value-objects/TeamRatingEventId';
import { TeamRatingEventOrmEntity } from '../entities/TeamRatingEventOrmEntity';
import { TeamRatingEventOrmMapper } from './TeamRatingEventOrmMapper';

describe('TeamRatingEventOrmMapper', () => {
  const validEntityProps = {
    id: '123e4567-e89b-12d3-a456-426614174000',
    teamId: 'team-123',
    dimension: 'driving',
    delta: 10,
    weight: 1,
    occurredAt: new Date('2024-01-01T00:00:00Z'),
    createdAt: new Date('2024-01-01T00:00:00Z'),
    source: { type: 'race' as const, id: 'race-456' },
    reason: { code: 'RACE_FINISH', description: 'Finished 1st in race' },
    visibility: { public: true },
    version: 1,
  };

  const validDomainProps = {
    id: TeamRatingEventId.create('123e4567-e89b-12d3-a456-426614174000'),
    teamId: 'team-123',
    dimension: TeamRatingDimensionKey.create('driving'),
    delta: TeamRatingDelta.create(10),
    weight: 1,
    occurredAt: new Date('2024-01-01T00:00:00Z'),
    createdAt: new Date('2024-01-01T00:00:00Z'),
    source: { type: 'race' as const, id: 'race-456' },
    reason: { code: 'RACE_FINISH', description: 'Finished 1st in race' },
    visibility: { public: true },
    version: 1,
  };

  describe('toDomain', () => {
    it('should convert ORM entity to domain entity', () => {
      const entity = Object.assign(new TeamRatingEventOrmEntity(), validEntityProps);
      const domain = TeamRatingEventOrmMapper.toDomain(entity);

      expect(domain.id.value).toBe(validEntityProps.id);
      expect(domain.teamId).toBe(validEntityProps.teamId);
      expect(domain.dimension.value).toBe(validEntityProps.dimension);
      expect(domain.delta.value).toBe(validEntityProps.delta);
      expect(domain.weight).toBe(validEntityProps.weight);
      expect(domain.occurredAt).toEqual(validEntityProps.occurredAt);
      expect(domain.createdAt).toEqual(validEntityProps.createdAt);
      expect(domain.source).toEqual(validEntityProps.source);
      expect(domain.reason).toEqual(validEntityProps.reason);
      expect(domain.visibility).toEqual(validEntityProps.visibility);
      expect(domain.version).toBe(validEntityProps.version);
    });

    it('should handle optional weight', () => {
      const entity = Object.assign(new TeamRatingEventOrmEntity(), {
        ...validEntityProps,
        weight: undefined,
      });
      const domain = TeamRatingEventOrmMapper.toDomain(entity);

      expect(domain.weight).toBeUndefined();
    });

    it('should handle null weight', () => {
      const entity = Object.assign(new TeamRatingEventOrmEntity(), {
        ...validEntityProps,
        weight: null,
      });
      const domain = TeamRatingEventOrmMapper.toDomain(entity);

      expect(domain.weight).toBeUndefined();
    });
  });

  describe('toOrmEntity', () => {
    it('should convert domain entity to ORM entity', () => {
      const domain = TeamRatingEvent.create(validDomainProps);
      const entity = TeamRatingEventOrmMapper.toOrmEntity(domain);

      expect(entity.id).toBe(validDomainProps.id.value);
      expect(entity.teamId).toBe(validDomainProps.teamId);
      expect(entity.dimension).toBe(validDomainProps.dimension.value);
      expect(entity.delta).toBe(validDomainProps.delta.value);
      expect(entity.weight).toBe(validDomainProps.weight);
      expect(entity.occurredAt).toEqual(validDomainProps.occurredAt);
      expect(entity.createdAt).toEqual(validDomainProps.createdAt);
      expect(entity.source).toEqual(validDomainProps.source);
      expect(entity.reason).toEqual(validDomainProps.reason);
      expect(entity.visibility).toEqual(validDomainProps.visibility);
      expect(entity.version).toBe(validDomainProps.version);
    });

    it('should handle domain entity without weight', () => {
      const props = { ...validDomainProps };
      delete (props as any).weight;
      const domain = TeamRatingEvent.create(props);
      const entity = TeamRatingEventOrmMapper.toOrmEntity(domain);

      expect(entity.weight).toBeUndefined();
    });
  });
});