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

class EmailVerificationRepository {
  constructor(unitOfWork) {
    this.unitOfWork = unitOfWork;
  }

  async upsertCode(userId, code, expiresAt) {
    logger.info('EmailVerificationRepository.upsertCode:start', { userId });
    const conn = this.unitOfWork.connection;
    try {
      // Try to update first
      const [result] = await conn.query(
        `UPDATE email_verifications SET verification_code = ?, expires_at = ?, verified_at = NULL, attempts = 0 WHERE user_id = ? AND (verified_at IS NULL OR expires_at > NOW())`,
        [code, expiresAt, userId]
      );
      if (result.affectedRows === 0) {
        // Insert if no row updated
        await conn.query(
          `INSERT INTO email_verifications (user_id, verification_code, expires_at) VALUES (?, ?, ?)`,
          [userId, code, expiresAt]
        );
      }
      logger.info('EmailVerificationRepository.upsertCode:success', { userId });
    } catch (error) {
      logger.error('EmailVerificationRepository.upsertCode:error', { userId, error: error.message });
      throw error;
    }
  }

  async getByUserId(userId) {
    logger.info('EmailVerificationRepository.getByUserId:start', { userId });
    const conn = this.unitOfWork.connection;
    try {
      const [rows] = await conn.query(
        `SELECT * FROM email_verifications WHERE user_id = ? ORDER BY id DESC LIMIT 1`,
        [userId]
      );
      logger.info('EmailVerificationRepository.getByUserId:success', { userId, found: rows.length > 0 });
      return rows.length > 0 ? rows[0] : null;
    } catch (error) {
      logger.error('EmailVerificationRepository.getByUserId:error', { userId, error: error.message });
      throw error;
    }
  }

  async incrementAttempts(id) {
    logger.info('EmailVerificationRepository.incrementAttempts:start', { id });
    const conn = this.unitOfWork.connection;
    try {
      await conn.query(
        `UPDATE email_verifications SET attempts = attempts + 1 WHERE id = ?`,
        [id]
      );
      logger.info('EmailVerificationRepository.incrementAttempts:success', { id });
    } catch (error) {
      logger.error('EmailVerificationRepository.incrementAttempts:error', { id, error: error.message });
      throw error;
    }
  }

  async setVerified(id) {
    logger.info('EmailVerificationRepository.setVerified:start', { id });
    const conn = this.unitOfWork.connection;
    try {
      await conn.query(
        `UPDATE email_verifications SET verified_at = NOW() WHERE id = ?`,
        [id]
      );
      logger.info('EmailVerificationRepository.setVerified:success', { id });
    } catch (error) {
      logger.error('EmailVerificationRepository.setVerified:error', { id, error: error.message });
      throw error;
    }
  }

  async getUserBasic(userId) {
    logger.info('EmailVerificationRepository.getUserBasic:start', { userId });
    const conn = this.unitOfWork.connection;
    try {
      const [rows] = await conn.query(
        `SELECT id, email FROM users WHERE id = ? LIMIT 1`,
        [userId]
      );
      logger.info('EmailVerificationRepository.getUserBasic:success', { userId, found: rows.length > 0 });
      return rows.length ? rows[0] : null;
    } catch (error) {
      logger.error('EmailVerificationRepository.getUserBasic:error', { userId, error: error.message });
      throw error;
    }
  }
}

module.exports = EmailVerificationRepository;
