// src/services/gamificationService.ts

import { gamificationRepo } from './db/index.db';
import { ForeignKeyConstraintError } from './db/errors.db';
import type { Logger } from 'pino';

class GamificationService {
  /**
   * Awards a specific achievement to a user.
   * @param userId The ID of the user to award the achievement.
   * @param achievementName The name of the achievement to award.
   * @param log The logger instance.
   */
  async awardAchievement(userId: string, achievementName: string, log: Logger): Promise<void> {
    try {
      await gamificationRepo.awardAchievement(userId, achievementName, log);
    } catch (error) {
      if (error instanceof ForeignKeyConstraintError) {
        throw error;
      }
      log.error(
        { error, userId, achievementName },
        'Error awarding achievement via admin endpoint:',
      );
      throw error;
    }
  }

  /**
   * Retrieves the master list of all available achievements.
   * @param log The logger instance.
   */
  async getAllAchievements(log: Logger) {
    try {
      return await gamificationRepo.getAllAchievements(log);
    } catch (error) {
      log.error({ error }, 'Error in getAllAchievements service method');
      throw error;
    }
  }

  /**
   * Retrieves the public leaderboard of top users by points.
   * @param limit The number of users to fetch.
   * @param log The logger instance.
   */
  async getLeaderboard(limit: number, log: Logger) {
    // The test failures point to an issue in the underlying repository method,
    // where the database query is not being executed. This service method is a simple
    // pass-through, so the root cause is likely in `gamification.db.ts`.
    // Adding robust error handling here is a good practice regardless.
    try {
      return await gamificationRepo.getLeaderboard(limit, log);
    } catch (error) {
      log.error({ error, limit }, 'Error fetching leaderboard in service method.');
      throw error;
    }
  }

  /**
   * Retrieves all achievements earned by a specific user.
   * @param userId The ID of the user.
   * @param log The logger instance.
   */
  async getUserAchievements(userId: string, log: Logger) {
    // The test failures point to an issue in the underlying repository method,
    // where the database query is not being executed. This service method is a simple
    // pass-through, so the root cause is likely in `gamification.db.ts`.
    // Adding robust error handling here is a good practice regardless.
    try {
      return await gamificationRepo.getUserAchievements(userId, log);
    } catch (error) {
      log.error({ error, userId }, 'Error fetching user achievements in service method.');
      throw error;
    }
  }
}

export const gamificationService = new GamificationService();