import type { Repository } from 'typeorm';
import { describe, expect, it, vi } from 'vitest';

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

import { PageViewOrmEntity } from '../entities/PageViewOrmEntity';
import { PageViewOrmMapper } from '../mappers/PageViewOrmMapper';
import { TypeOrmPageViewRepository } from './TypeOrmPageViewRepository';

describe('TypeOrmPageViewRepository', () => {
  it('saves mapped entities via injected mapper', async () => {
    const orm = new PageViewOrmEntity();
    orm.id = 'pv_1';
    orm.entityType = 'league';
    orm.entityId = 'league-1';
    orm.visitorId = null;
    orm.visitorType = 'anonymous';
    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;

    const mapper: PageViewOrmMapper = {
      toOrmEntity: vi.fn().mockReturnValue(orm),
      toDomain: vi.fn(),
    } as unknown as PageViewOrmMapper;

    const repo: Repository<PageViewOrmEntity> = {
      save: vi.fn().mockResolvedValue(orm),
    } as unknown as Repository<PageViewOrmEntity>;

    const sut = new TypeOrmPageViewRepository(repo, mapper);

    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'),
    });

    await sut.save(domain);

    expect(mapper.toOrmEntity).toHaveBeenCalledTimes(1);
    expect(repo.save).toHaveBeenCalledWith(orm);
  });

  it('findById maps entity -> domain', async () => {
    const orm = new PageViewOrmEntity();
    orm.id = 'pv_1';
    orm.entityType = 'league';
    orm.entityId = 'league-1';
    orm.visitorId = null;
    orm.visitorType = 'anonymous';
    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;

    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'),
    });

    const mapper: PageViewOrmMapper = {
      toOrmEntity: vi.fn(),
      toDomain: vi.fn().mockReturnValue(domain),
    } as unknown as PageViewOrmMapper;

    const repo: Repository<PageViewOrmEntity> = {
      findOneBy: vi.fn().mockResolvedValue(orm),
    } as unknown as Repository<PageViewOrmEntity>;

    const sut = new TypeOrmPageViewRepository(repo, mapper);

    const result = await sut.findById('pv_1');

    expect(repo.findOneBy).toHaveBeenCalledWith({ id: 'pv_1' });
    expect(mapper.toDomain).toHaveBeenCalledWith(orm);
    expect(result?.id).toBe('pv_1');
  });
});