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

import type { DataSource } from 'typeorm';

import { LeagueOrmMapper } from '../mappers/LeagueOrmMapper';
import { ResultOrmMapper } from '../mappers/ResultOrmMapper';
import { StandingOrmMapper } from '../mappers/StandingOrmMapper';
import { TypeOrmStandingRepository } from './TypeOrmStandingRepository';

describe('TypeOrmStandingRepository', () => {
  it('requires injected mappers (does not construct any internally)', () => {
    const dataSource = {} as DataSource;

    const standingMapper = new StandingOrmMapper();
    const resultMapper = new ResultOrmMapper();
    const leagueMapper = new LeagueOrmMapper();
    const pointsSystems: Record<string, Record<number, number>> = {};

    expect(() => new TypeOrmStandingRepository(dataSource, standingMapper, resultMapper, leagueMapper, pointsSystems)).not.toThrow();
  });

  it('uses TypeORM DataSource.getRepository (DB-free mocked repository)', async () => {
    const standingMapper = new StandingOrmMapper();
    const resultMapper = new ResultOrmMapper();
    const leagueMapper = new LeagueOrmMapper();
    const pointsSystems: Record<string, Record<number, number>> = {};

    const standingsRepoMock = {
      find: vi.fn(async () => []),
    };
    const resultsRepoMock = {
      find: vi.fn(async () => []),
    };

    const dataSource = {
      getRepository: vi.fn((entity: unknown) => {
        // Different repos per entity class; this mimics TypeORM behavior enough for constructor wiring tests.
        if (typeof entity === 'function' && (entity as { name?: string }).name === 'StandingOrmEntity') {
          return standingsRepoMock;
        }
        return resultsRepoMock;
      }),
    } as unknown as DataSource;

    const repo = new TypeOrmStandingRepository(dataSource, standingMapper, resultMapper, leagueMapper, pointsSystems);

    await repo.findByLeagueId('league-1');

    expect(dataSource.getRepository).toHaveBeenCalled();
    expect(standingsRepoMock.find).toHaveBeenCalled();
  });
});