import type { DataSource } from 'typeorm';

import type { IUserRepository, StoredUser } from '@core/identity/domain/repositories/IUserRepository';

import { UserOrmEntity } from '../entities/UserOrmEntity';
import { UserOrmMapper } from '../mappers/UserOrmMapper';

export class TypeOrmUserRepository implements IUserRepository {
  constructor(
    private readonly dataSource: DataSource,
    private readonly mapper: UserOrmMapper,
  ) {}

  async findByEmail(email: string): Promise<StoredUser | null> {
    const repo = this.dataSource.getRepository(UserOrmEntity);
    const entity = await repo.findOne({ where: { email: email.toLowerCase() } });
    return entity ? this.mapper.toStored(entity) : null;
  }

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

  async create(user: StoredUser): Promise<StoredUser> {
    const repo = this.dataSource.getRepository(UserOrmEntity);
    const entity = this.mapper.toOrmEntity({
      ...user,
      email: user.email.toLowerCase(),
    });
    await repo.save(entity);
    return user;
  }

  async update(user: StoredUser): Promise<StoredUser> {
    const repo = this.dataSource.getRepository(UserOrmEntity);
    const entity = this.mapper.toOrmEntity({
      ...user,
      email: user.email.toLowerCase(),
    });
    await repo.save(entity);
    return user;
  }

  async emailExists(email: string): Promise<boolean> {
    const repo = this.dataSource.getRepository(UserOrmEntity);
    const count = await repo.count({ where: { email: email.toLowerCase() } });
    return count > 0;
  }
}