import { sleep } from "../../../util";
import { getStoreLabel } from "../../../util/survey-utils/page-info";
import { Survey, TAnswerMethod } from "../../../util/survey-utils/survey";
import { TAnswerFlow, TSurveyQuestionType } from "./types";

const QUESTION_TYPE_TO_ANSWER_METHOD: Record<TSurveyQuestionType, TAnswerMethod> = {
  text: "input",
  radio: "radio",
};

function extractAnswerFromFlow(
  flowNumber: number,
  flows: Record<number, TAnswerFlow>,
  storeLabel: string,
  survey: Survey,
): string | null {
  const flow = flows[flowNumber];
  if (flow.answerDependency === "directAnswer") {
    return flow.answer(storeLabel).toString();
  }

  const dependencyAnswers: string[] = [];
  for (const key of flow.dependsOn.keys) {
    const targetFlow = flows[key];
    console.log(
      `Getting answer from dependency question '${targetFlow.questionLabel.toLogString()}'`,
    );

    const dependencyAnswer =
      targetFlow.sectionName === undefined
        ? survey.getAnswer(targetFlow.questionLabel)
        : survey.getAnswerBySection(targetFlow.sectionName, targetFlow.questionLabel);

    console.log(`Dependency answer is: ${dependencyAnswer}\n`);

    if (dependencyAnswer === null) {
      throw new Error(
        `dependency answer is null for question '${flow.questionLabel.toLogString()}'`,
      );
    }

    dependencyAnswers.push(dependencyAnswer);
  }

  const answer = flow.dependsOn.getAnswer(dependencyAnswers);
  if (answer === null) return null;

  return answer.toString();
}

export async function fillAnswerFlows(answerFlows: Record<number, TAnswerFlow>): Promise<void> {
  const survey = Survey.getInstance();
  const storeLabel = getStoreLabel();

  for (const [flowKey, flow] of Object.entries(answerFlows)) {
    let answer: string | null;
    try {
      answer = extractAnswerFromFlow(Number(flowKey), answerFlows, storeLabel, survey);
    } catch (error) {
      console.error(error);
      continue;
    }

    if (answer === null) {
      console.warn(`Projected answer is null for question '${flow.questionLabel.toLogString()}'`);
      continue;
    }

    const method = QUESTION_TYPE_TO_ANSWER_METHOD[flow.questionType];

    try {
      if (flow.sectionName === undefined) {
        survey.answer(method, flow.questionLabel, answer);
      } else {
        survey.answerBySection(method, flow.sectionName, flow.questionLabel, answer);
      }
    } catch (error) {
      console.error(error);
      continue;
    }

    await sleep(10);
  }
}
