import { beforeEach, describe, expect, it, vi } from 'vitest';
import type { Logger } from '@core/shared/application';
import { AnalyticsSnapshot } from '@core/analytics';
import { InMemoryAnalyticsSnapshotRepository } from './InMemoryAnalyticsSnapshotRepository';

describe('InMemoryAnalyticsSnapshotRepository', () => {
  let repository: InMemoryAnalyticsSnapshotRepository;
  let mockLogger: Logger;

  beforeEach(() => {
    mockLogger = {
      debug: vi.fn(),
      info: vi.fn(),
      warn: vi.fn(),
      error: vi.fn(),
    } as unknown as Logger;

    repository = new InMemoryAnalyticsSnapshotRepository(mockLogger);
    repository.clear();
  });

  it('initializes with logger', () => {
    expect(repository).toBeDefined();
    expect(mockLogger.info).toHaveBeenCalledWith('InMemoryAnalyticsSnapshotRepository initialized.');
  });

  it('saves and finds by id', async () => {
    const snapshot = AnalyticsSnapshot.createEmpty(
      'snap-1',
      'league',
      'league-1',
      'monthly',
      new Date('2025-01-01T00:00:00.000Z'),
      new Date('2025-02-01T00:00:00.000Z'),
    );

    await repository.save(snapshot);

    const found = await repository.findById('snap-1');
    expect(found).toBe(snapshot);
  });

  it('finds by entity and latest', async () => {
    const a = AnalyticsSnapshot.createEmpty(
      'snap-a',
      'league',
      'league-1',
      'monthly',
      new Date('2025-01-01T00:00:00.000Z'),
      new Date('2025-02-01T00:00:00.000Z'),
    );
    const b = AnalyticsSnapshot.createEmpty(
      'snap-b',
      'league',
      'league-1',
      'monthly',
      new Date('2025-02-01T00:00:00.000Z'),
      new Date('2025-03-01T00:00:00.000Z'),
    );
    const other = AnalyticsSnapshot.createEmpty(
      'snap-other',
      'team',
      'team-1',
      'monthly',
      new Date('2025-01-01T00:00:00.000Z'),
      new Date('2025-02-01T00:00:00.000Z'),
    );

    await repository.save(a);
    await repository.save(b);
    await repository.save(other);

    const byEntity = await repository.findByEntity('league', 'league-1');
    expect(byEntity.map(s => s.id).sort()).toEqual(['snap-a', 'snap-b']);

    const latest = await repository.findLatest('league', 'league-1', 'monthly');
    expect(latest?.id).toBe('snap-b');

    const history = await repository.getHistoricalSnapshots('league', 'league-1', 'monthly', 1);
    expect(history.map(s => s.id)).toEqual(['snap-b']);
  });

  it('finds by period range', async () => {
    const snapshot = AnalyticsSnapshot.createEmpty(
      'snap-period',
      'league',
      'league-1',
      'monthly',
      new Date('2025-01-01T00:00:00.000Z'),
      new Date('2025-02-01T00:00:00.000Z'),
    );

    await repository.save(snapshot);

    const found = await repository.findByPeriod(
      'league',
      'league-1',
      'monthly',
      new Date('2024-12-15T00:00:00.000Z'),
      new Date('2025-03-15T00:00:00.000Z'),
    );

    expect(found?.id).toBe('snap-period');
  });
});
