/**
 * Unit tests for UserRatingOrmMapper
 */

import { UserRating } from '@core/identity/domain/value-objects/UserRating';
import { UserRatingOrmEntity } from '../entities/UserRatingOrmEntity';
import { UserRatingOrmMapper } from './UserRatingOrmMapper';

describe('UserRatingOrmMapper', () => {
  describe('toDomain', () => {
    it('should convert ORM entity to domain value object', () => {
      const now = new Date('2024-01-01T10:00:00Z');
      const entity = new UserRatingOrmEntity();
      entity.userId = 'user-1';
      entity.driver = { value: 75, confidence: 0.5, sampleSize: 10, trend: 'rising', lastUpdated: now };
      entity.admin = { value: 60, confidence: 0.3, sampleSize: 5, trend: 'stable', lastUpdated: now };
      entity.steward = { value: 80, confidence: 0.4, sampleSize: 8, trend: 'falling', lastUpdated: now };
      entity.trust = { value: 70, confidence: 0.6, sampleSize: 12, trend: 'rising', lastUpdated: now };
      entity.fairness = { value: 85, confidence: 0.7, sampleSize: 15, trend: 'stable', lastUpdated: now };
      entity.overallReputation = 74;
      entity.calculatorVersion = '1.0';
      entity.createdAt = now;
      entity.updatedAt = now;

      const domain = UserRatingOrmMapper.toDomain(entity);

      expect(domain.userId).toBe(entity.userId);
      expect(domain.driver).toEqual(entity.driver);
      expect(domain.admin).toEqual(entity.admin);
      expect(domain.steward).toEqual(entity.steward);
      expect(domain.trust).toEqual(entity.trust);
      expect(domain.fairness).toEqual(entity.fairness);
      expect(domain.overallReputation).toBe(entity.overallReputation);
      expect(domain.calculatorVersion).toBe(entity.calculatorVersion);
      expect(domain.createdAt).toEqual(entity.createdAt);
      expect(domain.updatedAt).toEqual(entity.updatedAt);
    });

    it('should handle optional calculatorVersion', () => {
      const now = new Date('2024-01-01T10:00:00Z');
      const entity = new UserRatingOrmEntity();
      entity.userId = 'user-1';
      entity.driver = { value: 50, confidence: 0, sampleSize: 0, trend: 'stable', lastUpdated: now };
      entity.admin = { value: 50, confidence: 0, sampleSize: 0, trend: 'stable', lastUpdated: now };
      entity.steward = { value: 50, confidence: 0, sampleSize: 0, trend: 'stable', lastUpdated: now };
      entity.trust = { value: 50, confidence: 0, sampleSize: 0, trend: 'stable', lastUpdated: now };
      entity.fairness = { value: 50, confidence: 0, sampleSize: 0, trend: 'stable', lastUpdated: now };
      entity.overallReputation = 50;
      entity.createdAt = now;
      entity.updatedAt = now;

      const domain = UserRatingOrmMapper.toDomain(entity);

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

  describe('toOrmEntity', () => {
    it('should convert domain value object to ORM entity', () => {
      const domain = UserRating.create('user-1');
      const updated = domain.updateDriverRating(75);

      const entity = UserRatingOrmMapper.toOrmEntity(updated);

      expect(entity.userId).toBe(updated.userId);
      expect(entity.driver).toEqual(updated.driver);
      expect(entity.admin).toEqual(updated.admin);
      expect(entity.steward).toEqual(updated.steward);
      expect(entity.trust).toEqual(updated.trust);
      expect(entity.fairness).toEqual(updated.fairness);
      expect(entity.overallReputation).toBe(updated.overallReputation);
      expect(entity.calculatorVersion).toBe(updated.calculatorVersion);
      expect(entity.createdAt).toEqual(updated.createdAt);
      expect(entity.updatedAt).toEqual(updated.updatedAt);
    });

    it('should handle optional calculatorVersion', () => {
      const now = new Date('2024-01-01T10:00:00Z');
      const domain = UserRating.restore({
        userId: 'user-1',
        driver: { value: 60, confidence: 0.5, sampleSize: 10, trend: 'rising', lastUpdated: now },
        admin: { value: 50, confidence: 0, sampleSize: 0, trend: 'stable', lastUpdated: now },
        steward: { value: 50, confidence: 0, sampleSize: 0, trend: 'stable', lastUpdated: now },
        trust: { value: 50, confidence: 0, sampleSize: 0, trend: 'stable', lastUpdated: now },
        fairness: { value: 50, confidence: 0, sampleSize: 0, trend: 'stable', lastUpdated: now },
        overallReputation: 55,
        createdAt: now,
        updatedAt: now,
      });

      const entity = UserRatingOrmMapper.toOrmEntity(domain);

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

  describe('round-trip', () => {
    it('should preserve data through domain -> orm -> domain conversion', () => {
      const now = new Date('2024-01-01T10:00:00Z');
      const original = UserRating.restore({
        userId: 'user-1',
        driver: { value: 75, confidence: 0.5, sampleSize: 10, trend: 'rising', lastUpdated: now },
        admin: { value: 60, confidence: 0.3, sampleSize: 5, trend: 'stable', lastUpdated: now },
        steward: { value: 80, confidence: 0.4, sampleSize: 8, trend: 'falling', lastUpdated: now },
        trust: { value: 70, confidence: 0.6, sampleSize: 12, trend: 'rising', lastUpdated: now },
        fairness: { value: 85, confidence: 0.7, sampleSize: 15, trend: 'stable', lastUpdated: now },
        overallReputation: 74,
        calculatorVersion: '1.0',
        createdAt: now,
        updatedAt: now,
      });

      const entity = UserRatingOrmMapper.toOrmEntity(original);
      const restored = UserRatingOrmMapper.toDomain(entity);

      expect(restored.userId).toBe(original.userId);
      expect(restored.driver).toEqual(original.driver);
      expect(restored.admin).toEqual(original.admin);
      expect(restored.steward).toEqual(original.steward);
      expect(restored.trust).toEqual(original.trust);
      expect(restored.fairness).toEqual(original.fairness);
      expect(restored.overallReputation).toBe(original.overallReputation);
      expect(restored.calculatorVersion).toBe(original.calculatorVersion);
      expect(restored.createdAt).toEqual(original.createdAt);
      expect(restored.updatedAt).toEqual(original.updatedAt);
    });
  });
});