/**
 * @copyright 2026 NHCarrigan
 * @license Naomi's Public License
 * @author Naomi Carrigan
 */

import type { FastifyPluginAsync } from "fastify";
import {
  ACHIEVEMENT_LIST,
  ACHIEVEMENTS,
  AchievementProgress,
  UserAchievementSummary,
} from "@library/shared-types";
import { AchievementService } from "../../services/achievement.service";

const achievementsRoutes: FastifyPluginAsync = async (app) => {
  const achievementService = new AchievementService();

  /**
   * Get all achievement definitions (public route).
   */
  app.get("/definitions", async () => {
    return ACHIEVEMENT_LIST;
  });

  /**
   * Get a specific achievement definition by key (public route).
   */
  app.get<{ Params: { key: string } }>(
    "/definitions/:key",
    async (request, reply) => {
      const { key } = request.params;
      const achievement = ACHIEVEMENTS[key];

      if (!achievement) {
        return reply.notFound("Achievement not found");
      }

      return achievement;
    },
  );

  /**
   * Get current user's achievement summary (authenticated users).
   */
  app.get<{ Reply: UserAchievementSummary }>(
    "/summary",
    {
      preValidation: [app.authenticate],
    },
    async (request) => {
      const userId = request.user.id;
      const summary = await achievementService.getUserAchievementSummary(
        userId,
      );
      return summary;
    },
  );

  /**
   * Get current user's achievement progress (authenticated users).
   */
  app.get<{ Reply: AchievementProgress[] }>(
    "/progress",
    {
      preValidation: [app.authenticate],
    },
    async (request) => {
      const userId = request.user.id;
      const progress = await achievementService.getUserAchievementProgress(
        userId,
      );
      return progress;
    },
  );

  /**
   * Get another user's achievement summary by ID (authenticated users).
   */
  app.get<{ Params: { userId: string }; Reply: UserAchievementSummary }>(
    "/users/:userId/summary",
    {
      preValidation: [app.authenticate],
    },
    async (request, reply) => {
      const { userId } = request.params;

      try {
        const summary = await achievementService.getUserAchievementSummary(
          userId,
        );
        return summary;
      } catch (error) {
        return reply.notFound("User not found");
      }
    },
  );

  /**
   * Get another user's achievement progress by ID (authenticated users).
   */
  app.get<{ Params: { userId: string }; Reply: AchievementProgress[] }>(
    "/users/:userId/progress",
    {
      preValidation: [app.authenticate],
    },
    async (request, reply) => {
      const { userId } = request.params;

      try {
        const progress = await achievementService.getUserAchievementProgress(
          userId,
        );
        return progress;
      } catch (error) {
        return reply.notFound("User not found");
      }
    },
  );
};

export default achievementsRoutes;
