import { Repository } from 'typeorm';
import { INetworkRepository } from '../../../domain/repositories/network-repository';
import { PaginationOptions } from '../../../domain/repositories/pagination-options';
import { Network } from '../../../domain/entities/network';
import { NetworkEntity } from '../entities/network.entity';
import { AppDataSource } from '../data-source';
import { networkMapper } from './mappers/network.mapper';

export class TypeOrmNetworkRepository implements INetworkRepository {
  private get repository(): Repository<NetworkEntity> {
    return AppDataSource.getRepository(NetworkEntity);
  }

  async findById(id: string): Promise<Network | null> {
    const entity = await this.repository.findOneBy({ id });
    return entity ? networkMapper.toDomain(entity) : null;
  }

  async findByName(name: string): Promise<Network | null> {
    const entity = await this.repository.findOneBy({ name });
    return entity ? networkMapper.toDomain(entity) : null;
  }

  async findByChainId(chainId: number): Promise<Network | null> {
    const entity = await this.repository.findOneBy({ chainId });
    return entity ? networkMapper.toDomain(entity) : null;
  }

  async findActive(): Promise<Network[]> {
    const entities = await this.repository.find({
      where: { status: 'active' },
      order: { createdAt: 'DESC' },
    });
    return entities.map(networkMapper.toDomain);
  }

  async findAll(options?: PaginationOptions): Promise<Network[]> {
    const entities = await this.repository.find({
      take: options?.limit,
      skip: options?.offset,
      order: { createdAt: 'DESC' },
    });
    return entities.map(networkMapper.toDomain);
  }

  async save(network: Network): Promise<Network> {
    const entity = await this.repository.save(networkMapper.toEntity(network));
    return networkMapper.toDomain(entity);
  }

  async update(network: Network): Promise<Network> {
    const entity = await this.repository.save(networkMapper.toEntity(network));
    return networkMapper.toDomain(entity);
  }

  async delete(id: string): Promise<void> {
    await this.repository.delete(id);
  }
}
