import type Config from '../../types/config';
import type GPTAnswer from '../../types/gpt-answer';
import Logs from 'background/utils/logs';
import normalizeText from 'background/utils/normalize-text';
import { pickBestReponse } from 'background/utils/pick-best-response';
import {
  MoodleQuestionType,
  SingleChoiceResponse,
  TrueFalseResponse
} from '../../types/question-types';

/**
 * Handle input radio elements
 * @param config
 * @param inputList
 * @param gptAnswer
 */
function handleRadio(
  config: Config,
  inputList: NodeListOf<HTMLElement>,
  gptAnswer: GPTAnswer
): boolean {
  const firstInput = inputList?.[0] as HTMLInputElement;

  // Handle the case the input is not a radio
  if (!firstInput || firstInput.type !== 'radio') {
    return false;
  }

  let correctInput: HTMLInputElement | null = null;

  if (gptAnswer.response && gptAnswer.response.question_type === MoodleQuestionType.SINGLE_CHOICE) {
    const res = gptAnswer.response as SingleChoiceResponse;
    const index = res.correct_answer.index;
    if (index >= 0 && index < inputList.length) {
      correctInput = inputList[index] as HTMLInputElement;
    }
  } else if (
    gptAnswer.response &&
    gptAnswer.response.question_type === MoodleQuestionType.TRUE_FALSE
  ) {
    const res = gptAnswer.response as TrueFalseResponse;
    // In Moodle true/false typically true is index 0 and false is index 1 or vice-versa.
    // The query extracted options though... wait! True/false doesn't use `extractOptions`!
    // So we need to match text "true" or "false", or 1/0.
    const isTrue = res.correct_answer === true;

    // Quick fallback fuzzy to "true" or "false" if we don't know the exact indices
    // True/false has radio options, so we can search by text.
    const possibleAnswers = Array.from(inputList)
      .map(inp => ({
        element: inp,
        value: normalizeText(inp?.parentElement?.textContent ?? '')
      }))
      .filter(obj => obj.value !== '');

    const bestAnswer = pickBestReponse(isTrue ? 'true' : 'false', possibleAnswers);
    correctInput = bestAnswer.element as HTMLInputElement;
  } else {
    // Fallback parsing
    const possibleAnswers = Array.from(inputList)
      .map(inp => ({
        element: inp,
        value: normalizeText(inp?.parentElement?.textContent ?? '')
      }))
      .filter(obj => obj.value !== '');

    const bestAnswer = pickBestReponse(gptAnswer.rawResponse, possibleAnswers);

    if (config.logs && bestAnswer.value) {
      Logs.bestAnswer(bestAnswer.value, bestAnswer.similarity);
    }
    correctInput = bestAnswer.element as HTMLInputElement;
  }

  if (correctInput) {
    if (config.mouseover) {
      correctInput.addEventListener('mouseover', () => (correctInput as HTMLInputElement).click(), {
        once: true
      });
    } else {
      correctInput.click();
    }
  }

  return true;
}

export default handleRadio;
