import { TeamRatingSnapshot } from '@core/racing/domain/services/TeamRatingSnapshotCalculator';
import { TeamRatingValue } from '@core/racing/domain/value-objects/TeamRatingValue';
import { TeamRatingOrmEntity } from '../entities/TeamRatingOrmEntity';
import { TeamRatingOrmMapper } from './TeamRatingOrmMapper';

describe('TeamRatingOrmMapper', () => {
  const validEntityProps = {
    teamId: 'team-123',
    driving: {
      value: 65,
      confidence: 0.8,
      sampleSize: 10,
      trend: 'rising' as const,
      lastUpdated: new Date('2024-01-01T00:00:00Z'),
    },
    adminTrust: {
      value: 55,
      confidence: 0.8,
      sampleSize: 10,
      trend: 'stable' as const,
      lastUpdated: new Date('2024-01-01T00:00:00Z'),
    },
    overall: 62,
    calculatorVersion: '1.0',
    createdAt: new Date('2024-01-01T00:00:00Z'),
    updatedAt: new Date('2024-01-01T00:00:00Z'),
  };

  const validSnapshotProps: TeamRatingSnapshot = {
    teamId: 'team-123',
    driving: TeamRatingValue.create(65),
    adminTrust: TeamRatingValue.create(55),
    overall: 62,
    lastUpdated: new Date('2024-01-01T00:00:00Z'),
    eventCount: 10,
  };

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

      expect(snapshot.teamId).toBe(validEntityProps.teamId);
      expect(snapshot.driving.value).toBe(validEntityProps.driving.value);
      expect(snapshot.adminTrust.value).toBe(validEntityProps.adminTrust.value);
      expect(snapshot.overall).toBe(validEntityProps.overall);
      expect(snapshot.lastUpdated).toEqual(validEntityProps.updatedAt);
      expect(snapshot.eventCount).toBe(validEntityProps.driving.sampleSize + validEntityProps.adminTrust.sampleSize);
    });
  });

  describe('toOrmEntity', () => {
    it('should convert domain snapshot to ORM entity', () => {
      const entity = TeamRatingOrmMapper.toOrmEntity(validSnapshotProps);

      expect(entity.teamId).toBe(validSnapshotProps.teamId);
      expect(entity.driving.value).toBe(validSnapshotProps.driving.value);
      expect(entity.adminTrust.value).toBe(validSnapshotProps.adminTrust.value);
      expect(entity.overall).toBe(validSnapshotProps.overall);
      expect(entity.calculatorVersion).toBe('1.0');
      expect(entity.createdAt).toEqual(validSnapshotProps.lastUpdated);
      expect(entity.updatedAt).toEqual(validSnapshotProps.lastUpdated);
      
      // Check calculated confidence
      expect(entity.driving.confidence).toBeGreaterThan(0);
      expect(entity.driving.confidence).toBeLessThan(1);
      expect(entity.adminTrust.confidence).toBeGreaterThan(0);
      expect(entity.adminTrust.confidence).toBeLessThan(1);
      
      // Check sample size
      expect(entity.driving.sampleSize).toBe(validSnapshotProps.eventCount);
      expect(entity.adminTrust.sampleSize).toBe(validSnapshotProps.eventCount);
    });

    it('should calculate correct trend for rising driving rating', () => {
      const snapshot: TeamRatingSnapshot = {
        teamId: 'team-123',
        driving: TeamRatingValue.create(65),
        adminTrust: TeamRatingValue.create(50),
        overall: 60,
        lastUpdated: new Date('2024-01-01T00:00:00Z'),
        eventCount: 5,
      };

      const entity = TeamRatingOrmMapper.toOrmEntity(snapshot);
      expect(entity.driving.trend).toBe('rising');
    });

    it('should calculate correct trend for falling driving rating', () => {
      const snapshot: TeamRatingSnapshot = {
        teamId: 'team-123',
        driving: TeamRatingValue.create(35),
        adminTrust: TeamRatingValue.create(50),
        overall: 40,
        lastUpdated: new Date('2024-01-01T00:00:00Z'),
        eventCount: 5,
      };

      const entity = TeamRatingOrmMapper.toOrmEntity(snapshot);
      expect(entity.driving.trend).toBe('falling');
    });

    it('should calculate correct trend for stable driving rating', () => {
      const snapshot: TeamRatingSnapshot = {
        teamId: 'team-123',
        driving: TeamRatingValue.create(50),
        adminTrust: TeamRatingValue.create(50),
        overall: 50,
        lastUpdated: new Date('2024-01-01T00:00:00Z'),
        eventCount: 5,
      };

      const entity = TeamRatingOrmMapper.toOrmEntity(snapshot);
      expect(entity.driving.trend).toBe('stable');
    });
  });
});