import { describe, expect, it } from 'vitest';

import { PageView } from '@core/analytics/domain/entities/PageView';

import { PageViewOrmEntity } from '../entities/PageViewOrmEntity';
import { TypeOrmAnalyticsSchemaError } from '../errors/TypeOrmAnalyticsSchemaError';
import { PageViewOrmMapper } from './PageViewOrmMapper';

describe('PageViewOrmMapper', () => {
  it('maps domain -> orm -> domain (round-trip)', () => {
    const mapper = new PageViewOrmMapper();

    const domain = PageView.create({
      id: 'pv_1',
      entityType: 'league',
      entityId: 'league-1',
      visitorType: 'anonymous',
      sessionId: 'sess-1',
      timestamp: new Date('2025-01-01T00:00:00.000Z'),
      visitorId: 'visitor-1',
      referrer: 'https://example.com',
      userAgent: 'ua',
      country: 'DE',
      durationMs: 1234,
    });

    const orm = mapper.toOrmEntity(domain);
    expect(orm).toBeInstanceOf(PageViewOrmEntity);
    expect(orm.id).toBe(domain.id);

    const rehydrated = mapper.toDomain(orm);
    expect(rehydrated.id).toBe(domain.id);
    expect(rehydrated.entityType).toBe(domain.entityType);
    expect(rehydrated.entityId).toBe(domain.entityId);
    expect(rehydrated.sessionId).toBe(domain.sessionId);
    expect(rehydrated.visitorType).toBe(domain.visitorType);
    expect(rehydrated.visitorId).toBe(domain.visitorId);
    expect(rehydrated.referrer).toBe(domain.referrer);
    expect(rehydrated.userAgent).toBe(domain.userAgent);
    expect(rehydrated.country).toBe(domain.country);
    expect(rehydrated.durationMs).toBe(domain.durationMs);
    expect(rehydrated.timestamp.toISOString()).toBe(domain.timestamp.toISOString());
  });

  it('throws TypeOrmAnalyticsSchemaError for invalid persisted shape', () => {
    const mapper = new PageViewOrmMapper();

    const orm = new PageViewOrmEntity();
    orm.id = '';
    orm.entityType = 'league' as never;
    orm.entityId = 'league-1';
    orm.visitorId = null;
    orm.visitorType = 'anonymous' as never;
    orm.sessionId = 'sess-1';
    orm.referrer = null;
    orm.userAgent = null;
    orm.country = null;
    orm.timestamp = new Date('2025-01-01T00:00:00.000Z');
    orm.durationMs = null;

    expect(() => mapper.toDomain(orm)).toThrow(TypeOrmAnalyticsSchemaError);
  });
});