<template>
  <QuesBaseItem :info="info">
    <template v-slot:noMrgOption>
      <a-radio-group
        class="custom-radio-group"
        style="width: 100%"
        v-if="copyInfo.question_type === 1"
      >
        <draggable
          v-model="optionList"
          item-key="id"
          handle=".mover"
          chosenClass="chosen"
          animation="300"
          @end="sortOptionHandle"
        >
          <template #item="{ element, index }">
            <div class="choice-option-ele">
              <div
                style="height: 40px; line-height: 40px"
                :style="{ opacity: element.edit ? 0 : 1 }"
              >
                <i class="iconfont choice-option-ele-icon mover">&#xe6c3;</i>
              </div>
              <div class="tinymce-option" style="flex: 1">
                <div
                  class="choice-option-radio"
                  :class="{ 'choice-option-radio-active': element.edit }"
                >
                  <a-radio :value="element.id" class="choice-option-radio-item">
                  </a-radio>
                  <question-tinymce-option
                    v-model:html="element.option"
                    :ref="`tinymce_${index}`"
                    :preventKeyDown="true"
                    :hasAfter="!element.edit && element.is_other"
                    @keyDown="addOptionHandle(index)"
                    @focusChange="editChange($event, element, index)"
                  >
                    <template v-slot:content>
                      <div v-if="element.edit" class="choice-option-radio-btn">
                        <a-checkbox
                          :checked="Boolean(element.is_other)"
                          class="margin"
                          @change="otherChange($event, element)"
                          ><span style="color: #434343"
                            >设为其他项</span
                          ></a-checkbox
                        >
                        <div class="line" style="margin-right: 30px"></div>
                        <i
                          class="iconfont choice-option-radio-btn-remove margin"
                          @click="deleteOptionHandle(element.id)"
                          >&#xe6c5;</i
                        >
                      </div>
                    </template>
                  </question-tinymce-option>
                </div>
              </div>
            </div>
          </template>
        </draggable>
      </a-radio-group>
      <a-checkbox-group
        class="custom-checkbox-group"
        :value="checkGroups"
        style="width: 100%"
        v-else-if="copyInfo.question_type === 2"
        @change="groupChange"
      >
        <draggable
          v-model="optionList"
          item-key="id"
          handle=".mover"
          chosenClass="chosen"
          animation="300"
          @end="sortOptionHandle"
        >
          <template #item="{ element, index }">
            <div class="choice-option-ele">
              <div
                style="height: 40px; line-height: 40px"
                :style="{ opacity: element.edit ? 0 : 1 }"
              >
                <i class="iconfont choice-option-ele-icon mover">&#xe6c3;</i>
              </div>
              <div class="tinymce-option" style="flex: 1">
                <div
                  class="choice-option-radio"
                  :class="{ 'choice-option-radio-active': element.edit }"
                >
                  <a-checkbox
                    class="choice-option-radio-item"
                    style="margin-right: 8px"
                    :value="element.id"
                  >
                  </a-checkbox>
                  <question-tinymce-option
                    v-model:html="element.option"
                    :ref="`tinymce_${index}`"
                    :preventKeyDown="true"
                    :hasAfter="!element.edit && element.is_other"
                    @keyDown="addOptionHandle(index)"
                    @focusChange="editChange($event, element, index)"
                  >
                    <template v-slot:content>
                      <div v-if="element.edit" class="choice-option-radio-btn">
                        <a-checkbox-group
                          v-model:value="element.other"
                          @change="removeOtherChange(element)"
                        >
                          <a-checkbox value="remove" class="margin"
                            ><span style="color: #434343"
                              >设为排他项</span
                            ></a-checkbox
                          >
                          <a-checkbox value="other" class="margin"
                            ><span style="color: #434343"
                              >设为其他项</span
                            ></a-checkbox
                          >
                        </a-checkbox-group>
                        <div class="line" style="margin-right: 30px"></div>
                        <i
                          class="iconfont choice-option-radio-btn-remove margin"
                          @click="deleteOptionHandle(element.id)"
                          >&#xe6c5;</i
                        >
                      </div>
                    </template>
                  </question-tinymce-option>
                </div>
              </div>
            </div>
          </template>
        </draggable>
      </a-checkbox-group>
    </template>
    <template v-slot:footer>
      <a-button
        v-if="!disableUpdateBtn"
        type="text"
        class="custom-button"
        @click="addOptionHandle(optionList.length - 1)"
      >
        <div class="flex-align">
          <i class="iconfont">&#xe689;</i>
          <span style="margin-left: 6px">添加选项</span>
        </div>
      </a-button>
      <related-option v-if="!disableUpdateBtn" :info="info" />
      <option-show v-if="!disableUpdateBtn" :info="info" />
      <logical :info="info" />
      <BatchManageOptions
        v-if="!disableUpdateBtn"
        :info="info"
      ></BatchManageOptions>
    </template>
  </QuesBaseItem>
</template>

<script>
import draggable from "vuedraggable";
import { computed, ref } from "@vue/reactivity";
import Logical from "../../components/Logical.vue";
import { getCurrentInstance, nextTick, watch } from "@vue/runtime-core";
import Option from "../../mode/option.js";
import QuestionTinymceOption from "../../components/QuestionTinymceOption.vue";
import QuesBaseItem from "../../fragement/QuesBaseItem.vue";
import RelatedOption from "../../components/RelatedOption.vue";
import BatchManageOptions from "../../components/BatchManageOptions.vue";
import { useStore } from "vuex";
import OptionShow from "../../components/OptionShow.vue";
import * as cheerio from "cheerio";
import { message } from "ant-design-vue";
import { getOptionName } from "../../js/util.js";
export default {
  name: "Choice",
  components: {
    QuestionTinymceOption,
    draggable,
    Logical,
    QuesBaseItem,
    RelatedOption,
    BatchManageOptions,
    OptionShow,
  },
  props: {
    info: {
      type: Object,
      default: () => {},
    },
  },
  setup(props, context) {
    const store = useStore();
    const copyInfo = computed(() => {
      const info = JSON.parse(JSON.stringify(props.info));
      if (info.options[0]) {
        info.options[0].forEach((x) => {
          const other = [];
          if (x.is_remove_other) {
            other.push("remove");
          }
          if (x.is_other) {
            other.push("other");
          }
          x.other = other;
          x.check = false;
        });
      }
      return info;
    });
    const disableUpdateBtn = computed(() => {
      return props.info.permissions?.disable_update || false;
    });
    const optionList = ref([]);
    const checkGroups = ref([]);
    /** 修改选项 */
    const editChange = (e, element, index) => {
      element.edit = e;
      if (!element.edit) {
        const curUpdateOpt = props.info.options[0].find(
          (x) => x.id === element.id
        );
        if (
          curUpdateOpt.option !== element.option ||
          curUpdateOpt.is_other !== element.is_other ||
          curUpdateOpt.is_remove_other !== element.is_remove_other
        ) {
          // 选项验证重复
          const findIndex = optionSet(
            copyInfo.value.options[0],
            element,
            index
          );
          if (findIndex !== -1) {
            element.option = copyInfo.value.options[0][index].option;
            return;
          }
          optionList.value.forEach((opt) => {
            if (opt.id === element.id) {
              opt.option = element.option;
            }
          });
          emitInfo();
        }
      }
    };
    /** 多选题设为排他，其他 */
    const removeOtherChange = (element) => {
      element.is_remove_other = 0;
      element.is_other = 0;
      if (element.other.includes("remove")) {
        element.is_remove_other = 1;
      }
      if (element.other.includes("other")) {
        element.is_other = 1;
      }
    };
    /** 单选设为其他项 */
    const otherChange = (e, element) => {
      element.is_other = Number(e.target.checked);
    };
    const instance = getCurrentInstance();
    /** 新增选项 */
    const addOptionHandle = (index) => {
      const findIndex = optionSet(
        optionList.value,
        optionList.value[index],
        index
      );
      if (findIndex !== -1) {
        optionList.value[index].option =
          copyInfo.value.options[0][index].option;
      }
      const newOption = new Option();
      copyInfo.value.last_option_index++;
      newOption.option = `<p>选项${getOptionName(optionList.value)}</p>`;
      newOption.option_index = copyInfo.value.last_option_index;
      optionList.value.splice(index + 1, 0, newOption);
      // 解决在回车插入选项时，需要让新加的选项处于编辑状态，而不是还在之前位置
      nextTick(() => {
        const refs = instance.refs;
        refs[`tinymce_${index}`]?.onClickOutsides();
        refs[`tinymce_${index + 1}`]?.clickHandle();
      });
      emitInfo();
    };
    /**选项验重 */
    const optionSet = (optionList, element, index) => {
      const findIndex = optionList.findIndex((opt, fIndex) => {
        if (fIndex !== index) {
          const $old = cheerio
            .load(opt.option)
            .text()
            .replace(/\s*/g, "")
            .replaceAll("\n", "");
          const $new = cheerio
            .load(element.option)
            .text()
            .replace(/\s*/g, "")
            .replaceAll("\n", "");
          return $old === $new;
        }
      });
      if (findIndex !== -1) {
        message.error(
          `提示：第${index + 1}个选项和第${
            findIndex + 1
          }个选项重复，无法自动保存！`
        );
      }
      return findIndex;
    };
    /** 排序选项 */
    const sortOptionHandle = () => {
      emitInfo();
    };
    /** 删除选项 */
    const deleteOptionHandle = (id) => {
      optionList.value = optionList.value.filter((x) => x.id !== id);
      emitInfo();
    };
    const emitInfo = () => {
      const copyOptionList = optionList.value.map((opt) => {
        const temp = {
          ...opt,
        };
        delete temp.check;
        delete temp.other;
        delete temp.edit;
        return temp;
      });
      const tempCopyInfo = JSON.parse(JSON.stringify(copyInfo.value));
      tempCopyInfo.options[0] = copyOptionList;
      context.emit("update", tempCopyInfo);
    };
    const groupChange = (e) => {
      if (e.length) {
        const last = e[e.length - 1];
        const option = optionList.value.find((option) => option.id === last);
        if (option.is_remove_other) {
          e = [last];
        } else {
          e = e.filter((value) =>
            optionList.value.find(
              (option) => option.id === value && !option.is_remove_other
            )
          );
        }
      }
      checkGroups.value = e;
    };
    watch(
      copyInfo,
      (val) => {
        optionList.value = JSON.parse(
          JSON.stringify(val.options[0] ? copyInfo.value.options[0] : [])
        );
      },
      { immediate: true }
    );
    return {
      copyInfo,
      disableUpdateBtn,
      optionList,
      checkGroups,
      editChange,
      otherChange,
      removeOtherChange,
      addOptionHandle,
      deleteOptionHandle,
      sortOptionHandle,
      groupChange,
    };
  },
};
</script>

<style lang="scss" scoped>
.choice {
  &-option {
    &-ele {
      display: flex;
      margin-bottom: 18px;
      &-icon {
        font-size: 24px;
        cursor: move;
        opacity: 0;
        height: 40px;
        &:hover {
          color: $yili-default-color;
        }
      }
      &:hover .iconfont {
        opacity: 1;
      }
    }
    &-radio {
      display: flex;
      min-height: 40px;
      width: 100%;
      border-radius: 5px;
      border: 1px solid transparent;
      padding-left: 12px;
      &:hover {
        border: 1px dashed #8c8c8c;
      }
      &-item {
        height: 40px;
        line-height: 40px;
      }
      &-btn {
        display: flex;
        align-items: center;
        height: 40px;
        &-remove {
          font-size: 16px;
          cursor: pointer;
          color: #bfbfbf;
          &:hover {
            color: $yili-default-color;
          }
        }
      }
      &-active {
        background: #f5f5f5;
        border: 1px solid transparent !important;
      }
    }
  }
  .line {
    width: 1px;
    height: 16px;
    background: #d8d8d8;
    opacity: 0.2;
    border: 1px solid #979797;
  }
  .margin {
    margin-right: 30px;
  }
}
.chosen {
  background: #ffffff;
  box-shadow: 0px 4px 20px 0px rgba(0, 0, 0, 0.2);
}
</style>
