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

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

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

  async findRefreshToken(token) {
    logger.info('LoginRepository.findRefreshToken:start');
    try {
      const [rows] = await this.conn.query(
        `SELECT user_id, expires_at FROM refresh_tokens WHERE token = ? AND revoked_at IS NULL`,
        [token]
      );
      logger.info('LoginRepository.findRefreshToken:success', { found: !!rows.length });
      return rows.length ? rows[0] : null;
    } catch (error) {
      logger.error('LoginRepository.findRefreshToken:error', { error: error.message });
      throw error;
    }
  }

  async revokeRefreshToken(token) {
    logger.info('LoginRepository.revokeRefreshToken:start');
    try {
      await this.conn.query(
        `UPDATE refresh_tokens SET revoked_at = CURRENT_TIMESTAMP WHERE token = ?`,
        [token]
      );
      logger.info('LoginRepository.revokeRefreshToken:success');
    } catch (error) {
      logger.error('LoginRepository.revokeRefreshToken:error', { error: error.message });
      throw error;
    }
  }

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

  async getUserPermissions(userId) {
    logger.info('LoginRepository.getUserPermissions:start', { userId });
    try {
      const [permRows] = await this.conn.query(
        `SELECT p.name FROM user_permissions up
         JOIN permissions p ON up.permission_id = p.id
         WHERE up.user_id = ? AND p.is_active = TRUE`,
        [userId]
      );
      logger.info('LoginRepository.getUserPermissions:success', { userId, count: permRows.length });
      return permRows.map(row => row.name);
    } catch (error) {
      logger.error('LoginRepository.getUserPermissions:error', { userId, error: error.message });
      throw error;
    }
  }

  async getUserRole(userId) {
    logger.info('LoginRepository.getUserRole:start', { userId });
    try {
      const [roleRows] = await this.conn.query(
        `SELECT role FROM users WHERE id = ?`,
        [userId]
      );
      logger.info('LoginRepository.getUserRole:success', { userId, role: roleRows.length ? roleRows[0].role : null });
      return roleRows.length ? roleRows[0].role : null;
    } catch (error) {
      logger.error('LoginRepository.getUserRole:error', { userId, error: error.message });
      throw error;
    }
  }
}

module.exports = LoginRepository;
