import { randomUUID } from "crypto";
import { getGameTerms, getDistractors } from "@lila/db";
import type {
  GameQuestion,
  AnswerOption,
  SupportedLanguageCode,
  SupportedPos,
  DifficultyLevel,
} from "@lila/shared";

// TODO(game-mode-slice): replace with lobby settings when mode selection lands
const MULTIPLAYER_DEFAULTS = {
  sourceLanguage: "en" as SupportedLanguageCode,
  targetLanguage: "it" as SupportedLanguageCode,
  pos: "noun" as SupportedPos,
  difficulty: "easy" as DifficultyLevel,
  rounds: 3,
};

const shuffle = <T>(array: T[]): T[] => {
  const result = [...array];
  for (let i = result.length - 1; i > 0; i--) {
    const j = Math.floor(Math.random() * (i + 1));
    const temp = result[i]!;
    result[i] = result[j]!;
    result[j] = temp;
  }
  return result;
};

export type MultiplayerQuestion = GameQuestion & { correctOptionId: number };

export const generateMultiplayerQuestions = async (): Promise<
  MultiplayerQuestion[]
> => {
  const correctAnswers = await getGameTerms(
    MULTIPLAYER_DEFAULTS.sourceLanguage,
    MULTIPLAYER_DEFAULTS.targetLanguage,
    MULTIPLAYER_DEFAULTS.pos,
    MULTIPLAYER_DEFAULTS.difficulty,
    MULTIPLAYER_DEFAULTS.rounds,
  );

  const questions: MultiplayerQuestion[] = await Promise.all(
    correctAnswers.map(async (correctAnswer) => {
      const distractorTexts = await getDistractors(
        correctAnswer.termId,
        correctAnswer.targetText,
        MULTIPLAYER_DEFAULTS.targetLanguage,
        MULTIPLAYER_DEFAULTS.pos,
        MULTIPLAYER_DEFAULTS.difficulty,
        3,
      );

      const optionTexts = [correctAnswer.targetText, ...distractorTexts];
      const shuffledTexts = shuffle(optionTexts);
      const correctOptionId = shuffledTexts.indexOf(correctAnswer.targetText);

      const options: AnswerOption[] = shuffledTexts.map((text, index) => ({
        optionId: index,
        text,
      }));

      return {
        questionId: randomUUID(),
        prompt: correctAnswer.sourceText,
        gloss: correctAnswer.sourceGloss,
        options,
        correctOptionId,
      };
    }),
  );

  return questions;
};
