import { buildCardElements } from "./paperCard";

const COMMON_QUESTION_TYPES = [
  "SINGLE_ANSWER_QUESTION",
  "MULTIPLE_ANSWER_QUESTION",
  "BOOL_ANSWER_QUESTION",
  "FILL_BLANK_QUESTION",
  "TEXT_ANSWER_QUESTION",
];

function parseSimpleQuestion(simpleQuestion) {
  const [numbers, questionType, qinfo] = simpleQuestion.split(":");
  const [detailNo, questionNo, subQno] = numbers.split("-");
  return {
    detailNo: detailNo * 1,
    questionNo: questionNo * 1,
    subQno: subQno ? subQno * 1 : null,
    questionType,
    qinfo: qinfo * 1,
  };
}

function checkDetailIsOnlyOneNested(detail) {
  const firstQuestionNo = detail.questions[0].questionNo;
  return !detail.questions.some((q) => q.questionNo !== firstQuestionNo);
}

function parsePaperStruct(paperSimpleStruct) {
  // console.log(paperSimpleStruct);
  const dataList = paperSimpleStruct.split("#");
  const details = dataList.filter((item) => item.startsWith("detail"));
  let detailNames = {};
  details.forEach((detail) => {
    const pos = detail.indexOf("-");
    const detailNo = detail.substring(0, pos).replace("detail:", "") * 1;
    detailNames[detailNo] = detail.substring(pos + 1);
  });
  const questions = dataList
    .filter((item) => !item.startsWith("detail"))
    .map((q) => parseSimpleQuestion(q));

  // parse paper struct
  let detailList = [];
  questions.forEach((q) => {
    const dind = q.detailNo - 1;
    if (!detailList[dind]) {
      detailList[dind] = {
        detailNo: q.detailNo,
        detailName: detailNames[q.detailNo],
        questions: [],
      };
    }
    detailList[dind].questions.push(q);
  });

  let structList = [];
  detailList.forEach((detail) => {
    detail.isOnlyOneNested = checkDetailIsOnlyOneNested(detail);
    const commonQuestions = detail.questions.filter(
      (q) => COMMON_QUESTION_TYPES.includes(q.questionType) && q.subQno === null
    );
    if (commonQuestions.length) {
      const commonStructList = getCommonQuestionStructList(
        detail,
        commonQuestions,
        true,
        0
      );
      structList.push(...commonStructList);
    }

    const nestedQuestions = detail.questions.filter((q) => q.subQno !== null);
    if (nestedQuestions.length) {
      const nestedStructList = getNestedQuestionStructList(
        detail,
        nestedQuestions
      );
      structList.push(...nestedStructList);
    }
  });

  structList.sort((a, b) => a.sortNo - b.sortNo);
  // console.log(structList);
  return structList;
}

function getCommonQuestionStructList(
  detail,
  questions,
  isCommon,
  nestedQNo = 0
) {
  let structList = [];
  let structs = {};
  const qTypeNum = isCommon ? 1 : 2;
  questions.forEach((question) => {
    if (!structs[question.questionType]) structs[question.questionType] = [];
    structs[question.questionType].push(question);
  });
  Object.keys(structs).forEach((structType) => {
    const typeNo = COMMON_QUESTION_TYPES.indexOf(structType) + 1;
    const questions = parseCommonTypeQuestions(structType, structs[structType]);

    structList.push({
      detailName: detail.detailName,
      detailNo: detail.detailNo,
      isOnlyOneNested: detail.isOnlyOneNested,
      structType,
      isCommon,
      nestedQNo,
      sortNo:
        typeNo * 10000 + detail.detailNo * 1000 + qTypeNum * 100 + nestedQNo,
      questions,
    });
  });
  return structList;
}

function getNestedQuestionStructList(detail, questions) {
  let nestedQuestions = [];
  questions.forEach((question) => {
    const nestedNo = question.questionNo - 1;
    if (!nestedQuestions[nestedNo]) {
      nestedQuestions[nestedNo] = {
        questionNo: question.questionNo,
        subQuestions: [],
      };
    }
    nestedQuestions[nestedNo].subQuestions.push({
      ...question,
      questionNo: question.subQno,
    });
  });

  let structList = [];
  nestedQuestions.forEach((question) => {
    const qStructList = getCommonQuestionStructList(
      detail,
      question.subQuestions,
      false,
      question.questionNo
    );
    // console.log(qStructList);
    structList.push(...qStructList);
  });
  return structList;
}

function parseCommonTypeQuestions(structType, dataList) {
  const choiceQs = [
    "SINGLE_ANSWER_QUESTION",
    "MULTIPLE_ANSWER_QUESTION",
    "BOOL_ANSWER_QUESTION",
  ];
  let questions = [];
  if (choiceQs.includes(structType)) {
    questions = dataList.map((item) => {
      return {
        questionNo: item.questionNo,
        optionCount: structType === "BOOL_ANSWER_QUESTION" ? 2 : item.qinfo,
      };
    });
  } else if (structType === "FILL_BLANK_QUESTION") {
    questions = dataList.map((item) => {
      return {
        questionNo: item.questionNo,
        fillCount: item.qinfo,
      };
    });
  } else {
    questions = dataList.map((item) => item.questionNo);
  }
  return questions;
}

export function buildCardFromPaperSimpleStruct(
  paperSimpleStruct,
  elementTypePreSetInfo
) {
  const structList = parsePaperStruct(paperSimpleStruct);
  const cardElements = buildCardElements(structList, elementTypePreSetInfo);
  // console.log(cardElements);
  return cardElements;
}
