import type { DataSource } from 'typeorm';

import type { IPrizeRepository } from '@core/payments/domain/repositories/IPrizeRepository';
import type { Prize } from '@core/payments/domain/entities/Prize';

import { PaymentsPrizeOrmEntity } from '../entities/PaymentsPrizeOrmEntity';
import { PaymentsPrizeOrmMapper } from '../mappers/PaymentsPrizeOrmMapper';

export class TypeOrmPrizeRepository implements IPrizeRepository {
  constructor(
    private readonly dataSource: DataSource,
    private readonly mapper: PaymentsPrizeOrmMapper,
  ) {}

  async findById(id: string): Promise<Prize | null> {
    const repo = this.dataSource.getRepository(PaymentsPrizeOrmEntity);
    const entity = await repo.findOne({ where: { id } });
    return entity ? this.mapper.toDomain(entity) : null;
  }

  async findByLeagueId(leagueId: string): Promise<Prize[]> {
    const repo = this.dataSource.getRepository(PaymentsPrizeOrmEntity);
    const entities = await repo.find({ where: { leagueId } });
    return entities.map((e) => this.mapper.toDomain(e));
  }

  async findByLeagueIdAndSeasonId(leagueId: string, seasonId: string): Promise<Prize[]> {
    const repo = this.dataSource.getRepository(PaymentsPrizeOrmEntity);
    const entities = await repo.find({ where: { leagueId, seasonId } });
    return entities.map((e) => this.mapper.toDomain(e));
  }

  async findByPosition(leagueId: string, seasonId: string, position: number): Promise<Prize | null> {
    const repo = this.dataSource.getRepository(PaymentsPrizeOrmEntity);
    const entity = await repo.findOne({ where: { leagueId, seasonId, position } });
    return entity ? this.mapper.toDomain(entity) : null;
  }

  async create(prize: Prize): Promise<Prize> {
    const repo = this.dataSource.getRepository(PaymentsPrizeOrmEntity);
    await repo.save(this.mapper.toOrmEntity(prize));
    return prize;
  }

  async update(prize: Prize): Promise<Prize> {
    const repo = this.dataSource.getRepository(PaymentsPrizeOrmEntity);
    await repo.save(this.mapper.toOrmEntity(prize));
    return prize;
  }

  async delete(id: string): Promise<void> {
    const repo = this.dataSource.getRepository(PaymentsPrizeOrmEntity);
    await repo.delete({ id });
  }
}
