"use server";

import { revalidatePath } from "next/cache";
import { requireUser } from "@/lib/auth/requireUser";
import { mockPracticeModules } from "@/lib/data/mockPractice";
import { db } from "@/lib/prisma";
import { refreshStudyRecommendations } from "@/lib/recommendations";

type SubmitAttemptInput = {
  slug: string;
  selectedAnswers: number[];
};

type PracticePrismaClient = {
  miniGame: {
    upsert: (args: object) => Promise<{ id: string }>;
  };
  miniGameAttempt: {
    create: (args: object) => Promise<unknown>;
    findMany: (args: object) => Promise<
      { id: string; scorePercent: number; correctCount: number; totalQuestions: number; completedAt: Date }[]
    >;
  };
};

function toDifficulty(level?: string): "BEGINNER" | "INTERMEDIATE" | "ADVANCED" {
  if (level === "Beginner") return "BEGINNER";
  if (level === "Advanced") return "ADVANCED";
  return "INTERMEDIATE";
}

export async function submitPracticeAttempt({ slug, selectedAnswers }: SubmitAttemptInput) {
  const user = await requireUser();
  if (!user?.id) return { success: false as const, error: "Unauthorized" };

  const practiceModule = mockPracticeModules.find((item) => item.slug === slug && item.isInteractive && item.questions?.length);
  if (!practiceModule || !practiceModule.questions) return { success: false as const, error: "Practice module not found" };

  const correctCount = practiceModule.questions.reduce((acc, question, index) => {
    return acc + (selectedAnswers[index] === question.answerIndex ? 1 : 0);
  }, 0);
  const total = practiceModule.questions.length;
  const scorePercent = Math.round((correctCount / total) * 100);
  const prismaMini = db as unknown as PracticePrismaClient;

  try {
    const miniGame = await prismaMini.miniGame.upsert({
      where: { slug: practiceModule.slug },
      update: {
        title: practiceModule.title,
        description: practiceModule.description,
        isActive: true,
        difficulty: toDifficulty(practiceModule.difficulty),
      },
      create: {
        slug: practiceModule.slug,
        title: practiceModule.title,
        description: practiceModule.description,
        isActive: true,
        difficulty: toDifficulty(practiceModule.difficulty),
      },
      select: { id: true },
    });

    await prismaMini.miniGameAttempt.create({
      data: {
        userId: user.id,
        miniGameId: miniGame.id,
        scorePercent,
        correctCount,
        totalQuestions: total,
      },
    });

    await refreshStudyRecommendations(user.id);
  } catch {
    return { success: false as const, error: "Mini-game tables are not migrated yet" };
  }
  revalidatePath("/profile");

  return { success: true as const, scorePercent, correctCount, total };
}

export async function getPracticeAttempts(slug: string) {
  const user = await requireUser();
  if (!user?.id) return [];

  try {
    const attempts = await (db as unknown as PracticePrismaClient).miniGameAttempt.findMany({
      where: {
        userId: user.id,
        miniGame: {
          slug,
        },
      },
      orderBy: {
        completedAt: "desc",
      },
      take: 5,
      select: {
        id: true,
        scorePercent: true,
        correctCount: true,
        totalQuestions: true,
        completedAt: true,
      },
    });

    return attempts;
  } catch {
    return [];
  }
}
