const IUserRepository = require('../../domain/irepositories/IUserRepository');
const User = require('../../domain/models/User');

/**
 * User Repository Implementation
 * Prisma-based data access for User entity
 */
class UserRepository extends IUserRepository {
  constructor(prisma) {
    super();
    this.prisma = prisma;
  }

  /**
   * Find user by ID
   * @param {number} id 
   * @returns {Promise<User|null>}
   */
  async findById(id) {
    const userData = await this.prisma.user.findUnique({
      where: { id: parseInt(id) }
    });

    if (!userData) {
      return null;
    }

    return this._toDomain(userData);
  }

  /**
   * Find user by email
   * @param {string} email 
   * @returns {Promise<User|null>}
   */
  async findByEmail(email) {
    const userData = await this.prisma.user.findUnique({
      where: { email: email.toLowerCase() }
    });

    if (!userData) {
      return null;
    }

    return this._toDomain(userData);
  }

  /**
   * Find all users
   * @returns {Promise<User[]>}
   */
  async findAll() {
    const usersData = await this.prisma.user.findMany({
      orderBy: { createdAt: 'desc' }
    });

    return usersData.map(userData => this._toDomain(userData));
  }

  /**
   * Create new user
   * @param {User} user 
   * @returns {Promise<User>}
   */
  async create(user) {
    const userData = await this.prisma.user.create({
      data: {
        name: user.name,
        email: user.email,
        password: user.password
      }
    });

    return this._toDomain(userData);
  }

  /**
   * Update existing user
   * @param {User} user 
   * @returns {Promise<User>}
   */
  async update(user) {
    const userData = await this.prisma.user.update({
      where: { id: user.id },
      data: {
        name: user.name,
        email: user.email,
        password: user.password,
        updatedAt: new Date()
      }
    });

    return this._toDomain(userData);
  }

  /**
   * Delete user by ID
   * @param {number} id 
   * @returns {Promise<boolean>}
   */
  async delete(id) {
    try {
      await this.prisma.user.delete({
        where: { id: parseInt(id) }
      });
      return true;
    } catch (error) {
      return false;
    }
  }

  /**
   * Convert Prisma data to Domain model
   * @private
   * @param {Object} userData - Prisma user data
   * @returns {User}
   */
  _toDomain(userData) {
    return new User(
      userData.id,
      userData.name,
      userData.email,
      userData.password,
      userData.createdAt,
      userData.updatedAt
    );
  }
}

module.exports = UserRepository;
