import { router, publicProcedure, protectedProcedure } from "../_core/trpc.ts";
import { z } from "zod";
import {
  getPlayerStreak,
  updateLoginStreak,
  getPlayerBadges,
  getAvailableBadges,
  unlockBadge,
  getWeeklyChallenges,
  getPlayerChallenges,
  updateChallengeProgress,
  completeChallenge,
  getPlayerStats,
} from "../services/gamificationService.ts";

export const gamificationRouter = router({
  // Get player's login streak
  getStreak: protectedProcedure.query(async ({ ctx }) => {
    if (!ctx.user) throw new Error("User not authenticated");
    return await getPlayerStreak(ctx.user.id);
  }),

  // Update login streak (called on login)
  updateStreak: protectedProcedure.mutation(async ({ ctx }) => {
    if (!ctx.user) throw new Error("User not authenticated");
    return await updateLoginStreak(ctx.user.id);
  }),

  // Get player's unlocked badges
  getPlayerBadges: protectedProcedure.query(async ({ ctx }) => {
    if (!ctx.user) throw new Error("User not authenticated");
    return await getPlayerBadges(ctx.user.id);
  }),

  // Get all available badges
  getAvailableBadges: publicProcedure.query(async () => {
    return await getAvailableBadges();
  }),

  // Unlock a badge (internal use)
  unlockBadge: protectedProcedure
    .input(z.object({ badgeId: z.string() }))
    .mutation(async ({ input, ctx }) => {
      if (!ctx.user) throw new Error("User not authenticated");
      const success = await unlockBadge(ctx.user.id, input.badgeId);
      return { success, badgeId: input.badgeId };
    }),

  // Get weekly challenges
  getWeeklyChallenges: publicProcedure.query(async () => {
    return await getWeeklyChallenges();
  }),

  // Get player's challenge progress
  getPlayerChallenges: protectedProcedure.query(async ({ ctx }) => {
    if (!ctx.user) throw new Error("User not authenticated");
    return await getPlayerChallenges(ctx.user.id);
  }),

  // Update challenge progress
  updateChallengeProgress: protectedProcedure
    .input(
      z.object({
        challengeId: z.string(),
        progressDelta: z.number(),
      })
    )
    .mutation(async ({ input, ctx }) => {
      if (!ctx.user) throw new Error("User not authenticated");
      const challenge = await updateChallengeProgress(
        ctx.user.id,
        input.challengeId,
        input.progressDelta
      );
      return challenge;
    }),

  // Complete a challenge (internal use)
  completeChallenge: protectedProcedure
    .input(z.object({ challengeId: z.string() }))
    .mutation(async ({ input, ctx }) => {
      if (!ctx.user) throw new Error("User not authenticated");
      const reward = await completeChallenge(ctx.user.id, input.challengeId);
      return { success: true, challengeId: input.challengeId, reward };
    }),

  // Get player's gamification stats
  getStats: protectedProcedure.query(async ({ ctx }) => {
    if (!ctx.user) throw new Error("User not authenticated");
    return await getPlayerStats(ctx.user.id);
  }),
});
