<template>
  <div>
    <div v-if="showQuestionWhenPageLoad">
      <question-edit-drawer
        ref="editDrawer"
        v-model="questionEditDrawerVisible"
        :operation-type="operationType"
        :question="editingQuestion"
        @on-close="questionEditDrawClose"
        @on-open="questionEditDrawOpen"
      />
    </div>
    <div v-else class="survey-creator-wrapper">
      <Card :bordered="false" dis-hover>
        <Row align="middle" justify="space-between" type="flex">
          <Col span="20">
            <Icon class="icon-clipboard" custom="i-icon icon-clipboard" size="24"/>
            <span class="title">
                            {{ survey.name.text | translate(true) }}
                        </span>
          </Col>
          <Col>
            <Button icon="ios-arrow-back" @click="onBack">{{ t('survey_creator.common.back') }}</Button>
          </Col>
        </Row>
      </Card>

      <survey-internal-previewer
        v-if="isPreviewMode"
        :operation-type="operationType"
        :options="this.options"
        :survey="this.currentSurvey"
        style="height: calc(100vh - 130px);"
      ></survey-internal-previewer>

      <Card v-else :bordered="false" dis-hover style="height: calc(100vh - 130px);">
        <Tabs v-model="activeTab" type="card">
          <TabPane :label="t('survey_creator.common.tab.question_setting')" name="EDIT">
            <div v-if="activeTab === 'EDIT'">
              <Row :gutter="48" align="middle" class="survey-operate" justify="space-between" type="flex">
                <Col style="display: flex; align-items: center;">
                  <create-question-dropdown :options="options"/>
                  <slot name="add-question-extra"></slot>
                </Col>
                <Col>
                  <edit-options :survey="this.currentSurvey" class="edit-option"></edit-options>
                </Col>
              </Row>

              <div style="width: 100%;">
                <slot name="extra"></slot>
              </div>

              <Scroll :height="height" class="question-content">
                <survey-editor :options="this.options" :survey="this.currentSurvey"/>
              </Scroll>
            </div>
          </TabPane>
          <TabPane :label="t('survey_creator.common.tab.language')" name="TRANSLATE">
            <survey-translator
              v-if="activeTab === 'TRANSLATE'"
              :options="this.options"
              :survey="this.currentSurvey"
            />
          </TabPane>
        </Tabs>
      </Card>

      <question-edit-drawer
        ref="editDrawer"
        v-model="questionEditDrawerVisible"
        :operation-type="operationType"
        :question="editingQuestion"
      />

      <div v-if="questionJumpDrawerVisible" style="height: 100%">
        <question-jump-setting-drawer
          ref="jumpDrawer"
          v-model="questionJumpDrawerVisible"
          :from-question="jumpFromQuestion"
          :operation-type="operationType"
          :to-questions="jumpToQuestions"
        />
      </div>
      <div class="save-card">
        <Button
          :disabled="isSaved"
          :loading="loading"
          type="primary"
          @click="onSave"
        >{{ t(`survey_creator.common.save`) }}
        </Button>
      </div>
    </div>
  </div>
</template>
<script lang="ts">
import Vue from "vue";
import _ from "lodash";
import {Button, Card, Col, Icon, Modal, Row, Scroll, TabPane, Tabs} from "view-design";
import LocaleMixin from "../mixins/locale-mixin";
import SurveyTranslatorMixin from "../mixins/survey-translator-mixin";
import {BaseQuestionModel, QuestionFactory, QuestionMatrixModel, QuestionType, SubQuestionModel, SurveyLayout, SurveyModel} from "@wg-npm/survey-core";
import Toolbar from "./toolbar/toolbar.vue";
import SurveyEditor from "./editor/survey-editor.vue";
import QuestionEditDrawer from "./editor/question-edit-drawer.vue";
import SurveyTranslator from "./translator/survey-translator.vue";
import SurveyInternalPreviewer from "./previewer/survey-internal-previewer.vue";
import CreateQuestionDropdown from "./toolbar/create-question-dropdown.vue";
import EditOptions from "./editor/editor-options.vue";
import QuestionJumpSettingDrawer from "./editor/question-jump-setting-drawer.vue";
import {EventBus} from "../event-bus.js";

enum Mode {
  EDIT,
  TRANSLATE,
  PREVIEW
}

const QUESTION_OPERATION_TYPE_COPY = "copy";
const QUESTION_OPERATION_TYPE_CREATE = "create";
const QUESTION_OPERATION_TYPE_UPDATE = "update";
export default Vue.extend({
  name: "survey-creator",
  components: {
    Card,
    Row,
    Col,
    Button,
    SurveyEditor,
    SurveyTranslator,
    SurveyInternalPreviewer,
    QuestionEditDrawer,
    Toolbar,
    Modal,
    Tabs,
    TabPane,
    Icon,
    Scroll,
    CreateQuestionDropdown,
    EditOptions,
    QuestionJumpSettingDrawer
  },
  mixins: [LocaleMixin, SurveyTranslatorMixin],
  provide() {
    return {
      $rootComponent: this
    };
  },
  props: {
    loading: Boolean,
    survey: {
      type: Object as () => SurveyModel,
      required: true
    },
    showQuestionWhenPageLoad: {
      type: Boolean,
      required: false,
      default: false
    },
    showQuestionType: {
      type: String,
      required: false,
      default: QuestionType.EVALUATION
    },
    saveBtnAlwaysEnabled: {
      type: Boolean,
      default: false
    },
    options: {
      type: Object,
      required: false
    },
    screenshotData: {
      type: Object,
      required: false
    },
  },
  data: function () {
    return {
      height: window.innerHeight - 240,
      operationType: null,
      copyFromQuestionIndex: null,
      activeTab: Mode[Mode.EDIT],
      mode: Mode.EDIT,
      originSurvey: null,
      currentSurvey: null,
      primaryLanguage: null,
      editingQuestion: null,
      questionEditDrawerVisible: false,
      jumpFromQuestion: null,
      jumpToQuestions: null,
      questionJumpDrawerVisible: false,
      backHandler: {
        //@ts-ignore
        [Mode.EDIT]: this.onEditModeBack,
        //@ts-ignore
        [Mode.TRANSLATE]: this.onTranslateModeBack,
        //@ts-ignore
        [Mode.PREVIEW]: this.onPreviewModeBack
      }
    };
  },
  created() {
    this.originSurvey = _.cloneDeep(this.survey);
    this.currentSurvey = _.cloneDeep(this.survey);
    _.forEach(this.currentSurvey.questions, question => {
      this.$set(question, "active", false);
    });
    if (this.currentSurvey.questions.length > 0) {
      this.currentSurvey.questions[0].active = true;
    }
    this.primaryLanguage = _.camelCase(this.currentSurvey.options.primaryLanguage);

    if (this.showQuestionWhenPageLoad) {
      const question = _.find(this.currentSurvey?.questions, questions => {
        return questions.type === this.showQuestionType
      })
      if (_.isUndefined(question)) {
        this.createQuestion(this.showQuestionType)
      } else {
        this.showQuestionEditDrawer(<BaseQuestionModel>question)
      }
    }
  },
  computed: {
    isEditMode() {
      return this.mode === Mode.EDIT;
    },
    isTranslateMode() {
      return this.mode === Mode.TRANSLATE;
    },
    isPreviewMode() {
      return this.mode === Mode.PREVIEW;
    },
    isSaved() {
      return this.saveBtnAlwaysEnabled ? false : this.currentSurvey.questions.length === 0;
    }
  },
  watch: {
    survey(val) {
      this.originSurvey = _.cloneDeep(val);
    },
    screenshotData: {
      deep: true,
      handler(newValue) {
        if (Array.isArray(newValue.urls) && newValue.urls.length > 0) {
          EventBus.$emit("screen-shot-urls", newValue);
        }
      }
    }
  },
  mounted() {
    EventBus.$on("get-screen-shot-image", this.getScreenShot);
  },
  methods: {
    getScreenShot(message) {
      this.$emit("getScreenShot", message);
    },
    onEditModeBack() {
      this.$emit("on-back");
    },
    onTranslateModeBack() {
      this.mode = Mode.EDIT;
    },
    onPreviewModeBack() {
      this.mode = Mode.EDIT;
    },
    onBack() {
      this.$emit("on-back");
    },
    onSave() {
      if (this.validateData()) {
        this.$emit(
          "on-save",
          JSON.stringify(this.getPureSurvey(this.currentSurvey))
        );
        return;
      }

      if (this.showQuestionWhenPageLoad) {
        this.$emit(
          "on-save",
          JSON.stringify(this.getPureSurvey(this.currentSurvey))
        );
      } else {
        // @ts-ignore
        Modal.confirm({
          title: this.t("survey_creator.message.surveyLocaleNoSettingCompleted"),
          onOk: () => {
            this.$emit(
              "on-save",
              JSON.stringify(this.getPureSurvey(this.currentSurvey))
            );
          }
        });
      }
    },
    getPureSurvey(survey) {
      let temp = _.cloneDeep(survey);
      _.forEach(temp.questions, question => {
        this.$delete(question, "active");
      });
      return temp;
    },
    onTranslate() {
      this.mode = Mode.TRANSLATE;
    },
    onPreview() {
      this.mode = Mode.PREVIEW;
    },
    showQuestionEditDrawer(question: BaseQuestionModel) {
      this.editingQuestion = question;
      this.questionEditDrawerVisible = true;
    },
    showQuestionJumpDrawer(question: BaseQuestionModel, toQuestions) {
      this.jumpFromQuestion = question;
      this.jumpToQuestions = toQuestions;
      this.questionJumpDrawerVisible = true;
    },
    createQuestion(questionType: QuestionType) {
      this.operationType = QUESTION_OPERATION_TYPE_CREATE;
      let newQuestion = QuestionFactory.getInstance(
        this.primaryLanguage
      ).createQuestion(questionType);
      newQuestion.options.layout = this.currentSurvey.options.layout;
      this.showQuestionEditDrawer(newQuestion);
    },
    onLayoutChange(layout: SurveyLayout) {
      this.currentSurvey.options.layout = layout;
      _.forEach(
        this.currentSurvey.questions,
        question => (question.options.layout = layout)
      );
    },
    onQuestionCopy(id) {
      let fromIndex = _.findIndex(this.currentSurvey.questions, {id: id});
      if (fromIndex == -1) {
        return;
      }
      let fromQuestion = this.currentSurvey.questions[fromIndex];
      let copiedQuestion = this.createQuestionFrom(
        this.currentSurvey,
        fromQuestion
      );
      this.copyFromQuestionIndex = fromIndex;
      this.operationType = QUESTION_OPERATION_TYPE_COPY;
      this.showQuestionEditDrawer(copiedQuestion);
    },
    onQuestionCreateOrUpdate(newQuestion: BaseQuestionModel, operationType) {
      let existQuestionIndex = _.findIndex(this.currentSurvey.questions, {
        id: newQuestion.id
      });
      if (existQuestionIndex > -1) {
        Vue.set(this.currentSurvey.questions, existQuestionIndex, newQuestion);
      } else if (operationType == QUESTION_OPERATION_TYPE_COPY) {
        this.currentSurvey.questions.splice(
          this.copyFromQuestionIndex + 1,
          0,
          newQuestion
        );
      } else {
        this.currentSurvey.questions.push(newQuestion);
        this.$nextTick(() => {
          // @ts-ignore
          document.getElementById(newQuestion.id).scrollIntoView(true);
        });
      }
      BaseQuestionModel.refreshSurvey(this.currentSurvey);
      BaseQuestionModel.setActiveQuestion(
        newQuestion,
        this.currentSurvey.questions
      );

      if (this.showQuestionWhenPageLoad) {
        this.onSave()
      }
    },
    onQuestionDelete(id) {
      //删除某个问题时，判断是否为某个题目的跳转目标，若该题目为跳转目标题目，则需删除相关的逻辑跳转信息
      _.forEach(this.currentSurvey.questions, (question, index) => {
        let tempQuestion = _.cloneDeep(question);
        _.remove(tempQuestion.jumps, (jump: any) => jump.toQuestionId === id);
        Vue.set(this.currentSurvey.questions, index, tempQuestion);
      })
      _.remove(this.currentSurvey.questions, function (
        question: BaseQuestionModel
      ) {
        return question.id === id;
      });
      this.currentSurvey.questions = _.clone(this.currentSurvey.questions);
      BaseQuestionModel.refreshSurvey(this.currentSurvey);
    },
    onQuestionEdit(id) {
      // @ts-ignore
      let question: BaseQuestionModel = _.cloneDeep(
        _.find(this.currentSurvey.questions, {
          id: id
        })
      );
      this.operationType = QUESTION_OPERATION_TYPE_UPDATE;
      this.showQuestionEditDrawer(question);
    },
    onQuestionJump(id) {
      // @ts-ignore
      let question: BaseQuestionModel = _.cloneDeep(
        _.find(this.currentSurvey.questions, {
          id: id
        })
      );
      this.operationType = QUESTION_OPERATION_TYPE_UPDATE;
      let toQuestions = _.cloneDeep(
        _.filter(this.currentSurvey.questions, (item) => item.id != id
          && !(QuestionType.TEXT_TITLE === item.type)
          && !(QuestionType.EVALUATION === item.type)
        )
      );
      this.showQuestionJumpDrawer(question, toQuestions);
    },
    createQuestionFrom(survey, fromQuestion) {
      let newQuestion: BaseQuestionModel = _.cloneDeep(fromQuestion);
      newQuestion.id = BaseQuestionModel.createQuestionId();
      if (fromQuestion.type === QuestionType.MATRIX) {
        const subPrefix = SubQuestionModel.createSubPrefixId();
        (newQuestion as QuestionMatrixModel).subQuestions.forEach((element, index) => {
          (newQuestion as QuestionMatrixModel).subQuestions[index].id = subPrefix + index.toString();
        });
      }
      return newQuestion;
    },
    validateData() {
      return this.allTranslationIsCompleted(this.currentSurvey);
    },
    questionEditDrawOpen(val) {
      this.$emit("question-edit-draw-open");
    },
    questionEditDrawClose(val) {
      this.$emit("question-edit-draw-close");
    }
  }
});
</script>
