import { Repository } from 'typeorm';
import { IWalletRepository } from '../../../domain/repositories/wallet-repository';
import { Wallet } from '../../../domain/entities/wallet';
import { WalletEntity } from '../entities/wallet.entity';
import { AppDataSource } from '../data-source';
import { walletMapper } from './mappers/wallet.mapper';

export class TypeOrmWalletRepository implements IWalletRepository {
  private get repository(): Repository<WalletEntity> {
    return AppDataSource.getRepository(WalletEntity);
  }

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

  async findByDeviceId(deviceId: string): Promise<Wallet[]> {
    const entities = await this.repository
      .createQueryBuilder('wallet')
      .where("JSON_CONTAINS(wallet.deviceIds, :deviceId, '$')", {
        deviceId: JSON.stringify(deviceId),
      })
      .getMany();
    return entities.map(walletMapper.toDomain);
  }

  async findByDeviceIdAndName(deviceId: string, name: string): Promise<Wallet | null> {
    const entity = await this.repository
      .createQueryBuilder('wallet')
      .where("JSON_CONTAINS(wallet.deviceIds, :deviceId, '$')", {
        deviceId: JSON.stringify(deviceId),
      })
      .andWhere('wallet.name = :name', { name })
      .getOne();
    return entity ? walletMapper.toDomain(entity) : null;
  }

  async save(wallet: Wallet): Promise<Wallet> {
    const entity = await this.repository.save(walletMapper.toEntity(wallet));
    return walletMapper.toDomain(entity);
  }

  async update(wallet: Wallet): Promise<Wallet> {
    const entity = await this.repository.save(walletMapper.toEntity(wallet));
    return walletMapper.toDomain(entity);
  }

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