const { logger } = require('../../middleware/logger');

class PasswordResetRepository {
  constructor(unitOfWork) {
    this.unitOfWork = unitOfWork;
    this.conn = unitOfWork.connection;
  }

  async findValidTokenByUserId(userId) {
    logger.info('PasswordResetRepository.findValidTokenByUserId:start', { userId });
    try {
      const [rows] = await this.conn.query(
        `SELECT * FROM password_resets WHERE user_id = ? AND used_at IS NULL AND expires_at > NOW() LIMIT 1`,
        [userId]
      );
      logger.info('PasswordResetRepository.findValidTokenByUserId:success', { userId, found: rows.length > 0 });
      return rows.length > 0 ? rows[0] : null;
    } catch (error) {
      logger.error('PasswordResetRepository.findValidTokenByUserId:error', { userId, error: error.message });
      throw error;
    }
  }

  async createToken(userId, token, expiresAt) {
    logger.info('PasswordResetRepository.createToken:start', { userId, token, expiresAt });
    try {
      await this.conn.query(
        `INSERT INTO password_resets (user_id, token, expires_at) VALUES (?, ?, ?)`,
        [userId, token, expiresAt]
      );
      logger.info('PasswordResetRepository.createToken:success', { userId });
    } catch (error) {
      logger.error('PasswordResetRepository.createToken:error', { userId, error: error.message });
      throw error;
    }
  }

  async findValidToken(token) {
    logger.info('PasswordResetRepository.findValidToken:start', { token });
    try {
      const [rows] = await this.conn.query(
        `SELECT * FROM password_resets WHERE token = ? AND used_at IS NULL LIMIT 1`,
        [token]
      );
      const row = rows[0];
      logger.info('PasswordResetRepository.findValidToken:success', { token, found: !!row });
      if (!row || new Date(row.expires_at) < new Date()) {
        return null;
      }
      return row;
    } catch (error) {
      logger.error('PasswordResetRepository.findValidToken:error', { token, error: error.message });
      throw error;
    }
  }

  async updateUserPassword(userId, hashedPassword) {
    logger.info('PasswordResetRepository.updateUserPassword:start', { userId });
    try {
      await this.conn.query(
        `UPDATE users SET password = ? WHERE id = ?`,
        [hashedPassword, userId]
      );
      logger.info('PasswordResetRepository.updateUserPassword:success', { userId });
    } catch (error) {
      logger.error('PasswordResetRepository.updateUserPassword:error', { userId, error: error.message });
      throw error;
    }
  }

  async markTokenUsed(tokenId) {
    logger.info('PasswordResetRepository.markTokenUsed:start', { tokenId });
    try {
      await this.conn.query(
        `UPDATE password_resets SET used_at = NOW() WHERE id = ?`,
        [tokenId]
      );
      logger.info('PasswordResetRepository.markTokenUsed:success', { tokenId });
    } catch (error) {
      logger.error('PasswordResetRepository.markTokenUsed:error', { tokenId, error: error.message });
      throw error;
    }
  }
}

module.exports = PasswordResetRepository;
