<template>
  <div class="survey-internal-previewer-wrapper">
    <div
      v-if="enabledSelectQuestion || showCollapseToggle"
      class="question-selection-counter"
    >
      <img
        v-if="showCollapseToggle"
        :src="allExpanded ? arrowUpSvg : arrowDownSvg"
        class="collapse-toggle-all"
        @click="toggleAllExpand"
      />
      <Checkbox
        v-if="enabledSelectQuestion"
        :indeterminate="someSelected"
        :value="allSelected"
        @on-change="toggleSelectAll"
      />
      <template v-if="enabledSelectQuestion">
        {{
          t("survey_creator.previewer.counter_total", [sortQuestions.length])
        }}
        <span class="question-selection-counter__num">{{
          selectedQuestions.length
        }}</span>
        {{ t("survey_creator.previewer.counter_suffix") }}
      </template>
    </div>
    <previewer-question-row
      v-for="question in sortQuestions"
      :key="question.id"
      :ref="`question${question.id}`"
      :custom-question="surveyCustomQuestion(question.id)"
      :expanded="expandedMap[question.id]"
      :question="question"
      :survey="survey"
      @onSelectQuestion="onSelectQuestion"
      @singleQuestion="handleSelected"
      @toggle-expand="onToggleExpand(question.id)"
    ></previewer-question-row>
  </div>
</template>
<script lang="ts">
import Vue from "vue";
import { Card, Checkbox } from "view-design";
import arrowUpSvg from "../../images/arrow-up.svg";
import arrowDownSvg from "../../images/arrow-down.svg";
import { SurveyModel } from "@wg-npm/survey-core";
import PreviewerQuestionRow from "./previewer-question-row.vue";
import LocaleMixin from "../../mixins/locale-mixin";
import _ from "lodash";

export default Vue.extend({
  name: "survey-internal-previewer",
  components: { Card, Checkbox, PreviewerQuestionRow },
  mixins: [LocaleMixin],
  inject: {
    $rootComponent: { default: null },
  },
  props: {
    survey: {
      type: Object as () => SurveyModel,
      required: true,
    },
    initQuestionIds: {
      type: Array,
      required: false,
    },
    surveyCustomQuestions: {
      type: Array,
      required: false,
    },
  },
  data() {
    return {
      sortQuestions: this.survey.questions,
      selectedQuestions: [],
      expandedMap: Object.fromEntries(
        this.survey.questions.map((q) => [q.id, true])
      ) as Record<string, boolean>,
      arrowUpSvg,
      arrowDownSvg,
    };
  },
  mounted() {
    this.initSelectedQuestions();
  },
  computed: {
    questionsSort() {
      return this.sortQuestions;
    },
    questionIds() {
      return this.selectedQuestions.map((question) => question.id);
    },
    enabledSelectQuestion() {
      // @ts-ignore
      return _.get(this.$rootComponent, "options.enabledSelectQuestion", false);
    },
    showCollapseToggle() {
      // @ts-ignore
      return _.get(this.$rootComponent, "options.isPreviewMode", false);
    },
    allExpanded() {
      return this.sortQuestions.every((q) => this.expandedMap[q.id] !== false);
    },
    allSelected() {
      return (
        this.sortQuestions.length > 0 &&
        this.selectedQuestions.length === this.sortQuestions.length
      );
    },
    someSelected() {
      return (
        this.selectedQuestions.length > 0 &&
        this.selectedQuestions.length < this.sortQuestions.length
      );
    },
  },
  methods: {
    surveyCustomQuestion(questionId) {
      return _.find(this.surveyCustomQuestions, (q) => q.id === questionId);
    },
    setDisabled(item, disabled) {
      this.$set(item.options, "readonly", disabled);
    },
    handleSelected(selected) {
      if (selected) {
        let currentSingleQuestion = this.sortQuestions.find(
          (item) => item.id === selected.questionId
        );
        if (
          Array.isArray(currentSingleQuestion.jumps) &&
          currentSingleQuestion.jumps.length > 0
        ) {
          let target = currentSingleQuestion.jumps.find(
            (item) => item.choiceId === selected.choiceId
          );
          let disabledArr = currentSingleQuestion.jumps
            .filter((item) => item.choiceId !== selected.choiceId)
            .filter((item) => target.toQuestionId !== item.toQuestionId);
          if (target) {
            if (this.recordQuestionId === selected.questionId) {
              let resetItem = this.sortQuestions.find(
                (item) => item.id === target.toQuestionId
              );
              this.setDisabled(resetItem, false);
            }

            let nextQuestion = this.sortQuestions.find(
              (item) => item.id === target.toQuestionId
            );
            let selectedIndex = this.sortQuestions.findIndex(
              (item) => item.id === selected.questionId
            );
            let tmp: any = [];
            let startArr = this.sortQuestions.slice(0, selectedIndex + 1);
            startArr = startArr.filter(
              (item) => item.id !== target.toQuestionId
            );
            let endArr = this.sortQuestions
              .slice(selectedIndex + 1)
              .filter((item) => item.id !== target.toQuestionId);
            if (disabledArr.length > 0) {
              disabledArr.forEach((_item) => {
                let disabledQuestion = this.sortQuestions.find(
                  (item) => item.id === _item.toQuestionId
                );
                this.setDisabled(disabledQuestion, true);
              });
            }
            tmp = startArr;
            tmp.push(nextQuestion);
            tmp = tmp.concat(endArr);
            this.sortQuestions = tmp;
          }
        }
        this.recordQuestionId = selected.questionId;
      }
    },
    initSelectedQuestions() {
      if (
        Array.isArray(this.initQuestionIds) &&
        this.initQuestionIds.length > 0
      ) {
        this.initQuestionIds.forEach((id) => {
          const question = this.sortQuestions.find((item) => item.id === id);
          question && this.selectQuestionHandler(true, question);
        });
        this.sortSelectedQuestions();
        this.$emit("selected-question-ids", this.questionIds);
      }
    },
    onSelectQuestion(selected, question) {
      if (selected) {
        this.selectQuestionHandler(selected, question);
      } else {
        this.unSelectQuestionHandler(selected, question);
      }
      this.sortSelectedQuestions();
      this.$emit("selected-question-ids", this.questionIds);
    },
    selectQuestionHandler(selected, question) {
      this.$refs[`question${question.id}`][0].selectQuestion(selected);
      this.selectedQuestions.find((i) => i.id === question.id) ||
        this.selectedQuestions.push(question);
      if (Array.isArray(question.jumps) && question.jumps.length > 0) {
        question.jumps.forEach((item) => {
          const jumpItem = this.sortQuestions.find(
            (i) => item.toQuestionId === i.id
          );
          if (
            jumpItem &&
            !this.selectedQuestions.find((i) => i.id === jumpItem.id)
          ) {
            this.selectQuestionHandler(selected, jumpItem);
          }
        });
      }
    },
    unSelectQuestionHandler(selected, question) {
      this.$refs[`question${question.id}`][0].selectQuestion(selected);
      // @ts-ignore
      _.remove(this.selectedQuestions, (q) => q.id === question.id);
      this.sortQuestions.forEach((item) => {
        if (Array.isArray(item.jumps) && item.jumps.length > 0) {
          const jumpItem = item.jumps.find(
            (i) => i.toQuestionId === question.id
          );
          if (
            jumpItem &&
            this.selectedQuestions.find((i) => i.id === item.id)
          ) {
            this.unSelectQuestionHandler(selected, item);
          }
        }
      });
    },
    toggleSelectAll(checked) {
      if (checked) {
        this.sortQuestions
          .filter((q) => !this.selectedQuestions.find((i) => i.id === q.id))
          .forEach((q) => this.selectQuestionHandler(true, q));
      } else {
        this.sortQuestions.forEach((q) =>
          (this.$refs[`question${q.id}`] as any[])[0]?.selectQuestion(false)
        );
        (this.selectedQuestions as any[]).splice(0, Infinity);
      }
      this.sortSelectedQuestions();
      this.$emit("selected-question-ids", this.questionIds);
    },
    onToggleExpand(questionId) {
      this.$set(this.expandedMap, questionId, !this.expandedMap[questionId]);
    },
    toggleAllExpand() {
      const newState = !this.allExpanded;
      this.sortQuestions.forEach((q) => {
        this.$set(this.expandedMap, q.id, newState);
      });
    },
    sortSelectedQuestions() {
      this.selectedQuestions.sort((first, second) => {
        if (first.header.number > second.header.number) {
          return 1;
        }
        if (first.header.number < second.header.number) {
          return -1;
        }
        return 0;
      });
    },
  },
});
</script>
