<template>
  <div class="design-create">
    <draggable
      v-if="questionInfo.questions.length > 0"
      v-model:data="questionInfo.questions"
      item-key="id"
      handle=".moveQuestion"
      chosenClass="chosen"
      animation="300"
      :scroll="true"
    >
      <template #item="{ element, index }">
        <choose-question
          :element="element"
          :questions="questionInfo.questions"
          :index="index"
          :chooseQuestionId="chooseQuestionId"
          :questionsInfo="questionInfo"
          @get-choose-question-id="getChooseQuestionId"
          @move="emitFun.move"
          @copy="emitFun.copy"
          @delete="emitFun.delete"
          @setting="emitFun.setting"
          @logics="emitFun.logics"
        >
          <!-- 打分题 -->
          <Rate
            v-if="element.question_type === 5"
            :element="computedElement(element)"
            :index="index"
            :active="chooseQuestionId === element.id"
            @update:element="updateElement"
          />
          <!-- 选择题 -->
          <Choice
            v-if="element.question_type === 1 || element.question_type === 2"
            :index="index"
            :active="chooseQuestionId === element.id"
            :element="computedElement(element)"
            @update:element="updateElement"
          ></Choice>
          <!-- 填空题 -->
          <Completion
            v-if="element.question_type === 4"
            :index="index"
            :element="computedElement(element)"
            :active="chooseQuestionId === element.id"
            @update:element="updateElement"
          ></Completion>

          <!-- 矩阵题 -->
          <matrix-question
            v-if="
              element.question_type === 8 ||
              element.question_type === 9 ||
              element.question_type === 10
            "
            v-model:cols="element.options[1]"
            v-model:rows="element.options[0]"
            :element="computedElement(element)"
            :index="index"
            :active="chooseQuestionId === element.id"
            @update:element="updateElement"
          />

          <!-- 签名题 -->
          <sign-question
            v-if="[22].includes(element.question_type)"
            :element="computedElement(element)"
            :index="index"
            :active="chooseQuestionId === element.id"
            @update:element="updateElement"
          />

          <!-- 文件上传题 -->
          <file-upload
            v-if="element.question_type === 18"
            :element="computedElement(element)"
            :index="index"
            :active="chooseQuestionId === element.id"
            @update:element="updateElement"
          />

          <!--图文-->
          <TextWithImages
            v-if="element.question_type === 6"
            :element="computedElement(element)"
            :index="index"
            :active="chooseQuestionId === element.id"
            @update:element="updateElement"
          />
          <!--NPS-->
          <NPS
            v-if="element.question_type === 106"
            :element="computedElement(element)"
            :index="index"
            :active="chooseQuestionId === element.id"
            @update:element="updateElement"
          />
          <!--组件底部左侧操作-->
          <template #action="{ element: el }">
            <div v-if="el.id === chooseQuestionId" class="flex slot-actions">
              <template v-for="(item, optionIndex) in actionOptions">
                <div
                  v-if="item.question_type.includes(el.question_type)"
                  :key="optionIndex"
                  class="flex"
                >
                  <template v-for="(act, actIndex) in item.actions" :key="actIndex">
                    <div
                      class="flex align-center action-item theme-color"
                      @click="actionEvent(act, el)"
                    >
                      <van-icon :name="act.icon" class="icons"></van-icon>
                      <span class="ml10">{{ act.label }}</span>
                    </div>
                  </template>
                </div>
              </template>
            </div>
          </template>
        </choose-question>
        <!--         增加控制按钮-->
        <slot name="button" :item="element"></slot>
        <div v-if="!filterGap">
          <paging
            v-if="!element.question_type && questionInfo.survey.pages.length > 1"
            :info="element"
            :index="index"
            :active="pageIsActive(activeIndex, questionInfo.questions, element.page)"
            @click.stop=""
          />
        </div>
      </template>
    </draggable>
    <div v-else>
      <slot name="empty"></slot>
    </div>
  </div>
</template>
<script setup>
import { v4 as uuidv4 } from 'uuid';
import * as Base64 from 'js-base64';
import { ref, watch, computed, reactive } from 'vue';
import { useCounterStore } from '@/stores/counter';
import { storeToRefs } from 'pinia';
import { useRoute } from 'vue-router';
import { saveQuestion, sync } from '@/api/design/index.js';
import Draggable from './components/Draggable.vue';
import Choice from './components/Questions/Choice.vue';
import ChooseQuestion from './components/ChooseQuestion.vue';
import Paging from './components/Questions/paging/Paging.vue';
import Completion from './components/Questions/Completion.vue';
import MatrixQuestion from './components/Questions/MatrixQuestion.vue';
import Rate from './components/Questions/Rate.vue';
import TextWithImages from '@/views/Design/components/Questions/TextWithImages.vue';
import SignQuestion from './components/Questions/SignQuestion.vue';
import FileUpload from './components/Questions/FileUpload.vue';
import NPS from '@/views/Design/components/Questions/NPS.vue';
import { getPages } from '@/utils/public';
import { debounce } from '@/utils/utils';

const activeIndex = ref(-1);
const route = useRoute();
// 获取所有的 question 列表内容
const { filterGap, activeId } = defineProps({
  filterGap: {
    type: Boolean,
    required: false,
    default: false
  },
  activeId: {
    type: [String, Number],
    default: ''
  }
});
// 是否是预览
const isPreview = defineModel('isPreview', {
  type: Boolean,
  default: false
});
const computedElement = computed(() => (element) => {
  return reactive({
    ...element,
    // 添加需要响应式的属性
    options: element.options.map((opt) => reactive(opt))
  });
});

watch(
  () => activeId,
  (newVal) => {
    chooseQuestionId.value = newVal;
  }
);

/**
 * 工具函数
 */
function util() {
  /** 通过id找到数组中对应的下标 */
  const getIndexById = (arr, id) => arr.findIndex((i) => i.id === id);
  /** 通过分页找到数组中对应的下标 */
  const getIndexByPage = (arr, page) => arr.findIndex((i) => i.page === page);
  const quesIsActive = (activeIndex, questionList, eleId) => {
    return activeIndex === getIndexById(questionList, eleId);
  };
  const pageIsActive = (activeIndex, questionList, elePage) => {
    return activeIndex === getIndexByPage(questionList, elePage);
  };
  const quesIsDisabled = (questionIndex, disabledQuestionIndex) => {
    return (disabledQuestionIndex || []).includes(questionIndex);
  };
  const pagingDisabled = (index, question, disabledQuestionIndex) => {
    if (disabledQuestionIndex.includes(question?.[index - 1]?.questionIndex)) {
      return true;
    }
    for (let i = 1; i < question.length - 1; i++) {
      if (question?.[index + i]?.page) {
        continue;
      }
      if (disabledQuestionIndex.includes(question?.[index + i]?.questionIndex)) {
        return true;
      }
    }
    return false;
  };
  /** 工具函数，复制store中的数据，避免直接更改store */
  const copyStoreContent = (store) => {
    return JSON.parse(JSON.stringify(store.state.common));
  };
  return {
    getIndexById,
    getIndexByPage,
    quesIsActive,
    pageIsActive,
    quesIsDisabled,
    pagingDisabled,
    copyStoreContent
  };
}

const { pageIsActive } = util();
// 获取 Store 实例
const counterStore = useCounterStore();
const store = storeToRefs(counterStore);

const chooseQuestionId = ref('');
const chooseQuestionIndex = ref(-1);

let questionInfo = computed(() => store.questionsInfo.value);

const previewQuestionInfo = defineModel('previewQuestionInfo', {
  type: Object
});

if (previewQuestionInfo.value?.answer) {
  questionInfo = previewQuestionInfo;
}

// 自动更新 题型
// 利用防抖减少请求的频率
// 在 watch 外部创建一个防抖函数
const debouncedSaveQueItem = debounce((logics, newVal) => {
  if (newVal && !isPreview.value) {
    saveQueItem(logics, newVal);

    let questionCopy = JSON.parse(JSON.stringify(questionInfo.value.questions));
    // questionCopy = questionCopy.map((item, index) => {
    //   return {
    //     ...item,
    //     title: index + 1
    //   };
    // });
    // 保存全部  更新title
    // saveQueItem(questionInfo.value.logics, questionCopy);
  }
}, 1000);

// 在 watch 回调中调用这个已经防抖过的函数
watch(
  () => questionInfo.value.questions.filter((item) => item.id === chooseQuestionId.value),
  (newVal) => {
    debouncedSaveQueItem(questionInfo.value.logics, newVal);
    // saveQueItem(questionInfo.value.logics, newVal);
  },
  { deep: true }
);

const emit = defineEmits(['getActiveQuestion']);
// 获取选中的题目的ID
const getChooseQuestionId = (questionItem, index) => {
  chooseQuestionId.value = questionItem.id;
  chooseQuestionIndex.value = index;
  // 向外传出选中的题目
  emit('getActiveQuestion', questionItem);
};
// 组件对应的操作
const actionOptions = [
  {
    question_type: [1, 2, 5],
    actions: [
      {
        label: '添加选项',
        icon: 'add-o',
        fun: 'radioAddOption'
      }
    ]
  },
  {
    question_type: [8, 9, 10],
    // 矩阵问卷逻辑处理
    actions: [
      {
        label: '添加行标签',
        icon: 'add-o',
        fun: 'addMatrixRowOption'
      },
      {
        label: '添加列标签',
        icon: 'add-o',
        fun: 'addMatrixColumnOption'
      }
    ]
  }
];
//  事件分发
const actionEvent = (item, el) => {
  actionFun[item.fun](el);
};
// 总事件注册
const actionFun = {
  //  单选事件  添加选项 无限制添加
  radioAddOption: (element) => {
    element.options.map((item) => {
      item.push({
        id: uuidv4(),
        option: `选项${item.length + 1}`,
        option_config: {
          image_url: [],
          title: '',
          instructions: [],
          option_type: 0,
          limit_right_content: ''
        },
        option_index: element.last_option_index + 1,
        parent_id: 0,
        type: 1,
        cascade: [],
        config: []
      });
    });
    element.last_option_index += 1;

    saveQueItem(questionInfo.value.logics, [element]);
  },

  /**
   * martrix 矩阵行数增加
   * @param element {import('./components/Questions/types/martrix.js').MatrixSurveyQuestion}
   */
  addMatrixRowOption: (element) => {
    element.last_option_index = element.last_option_index + 1;
    element.options[0].push({
      cascade: [],
      config: [],
      is_fixed: 0,
      is_other: 0,
      is_remove_other: 0,
      option: `<p>行标签${element.options[0].length + 1}</p>`,
      option_config: {
        image_url: [],
        title: '',
        instructions: [],
        option_type: 0,
        type: 1,
        limit_right_content: '<p>右极文字1</p>'
      },
      parent_id: 0,
      type: 1,
      id: uuidv4(),
      option_index: element.last_option_index
    });

    saveQueItem(questionInfo.value.logics, [element]);
  },
  /**
   * martrix 矩阵列数增加
   * @param element {import('./components/Questions/types/martrix.js').MatrixSurveyQuestion}
   */
  addMatrixColumnOption: (element) => {
    const optionIndex = element.last_option_index;
    element.options[1].push({
      cascade: [],
      config: [],
      is_fixed: 0,
      is_other: 0,
      is_remove_other: 0,
      option: `<p>列标签${element.options[1].length + 1}</p>`,
      option_config: {
        image_url: [],
        title: '',
        instructions: [],
        option_type: 0,
        type: 2,
        limit_right_content: '<p>右极文字1</p>'
      },
      parent_id: 0,
      type: 2,
      id: uuidv4(),
      option_index: optionIndex + 1
    });

    element.last_option_index = optionIndex + 1;
    saveQueItem(questionInfo.value.logics, [element]);
  }
};

// emit 事件
const saveQueItem = (logics, questions, survey) => {
  if (route.query.sn) {
    saveQuestion({
      sn: route.query.sn,
      data: {
        logics: logics || [],
        questions: questions || [],
        survey: {
          local_pages: [],
          ...survey,
          pages: getPages(
            questionInfo.value.questions,
            questionInfo.value.survey.is_one_page_one_question
          ),
          version: Base64.encode(`${new Date().getTime()}`)
        }
      }
    }).then(() => {
      sync({ sn: route.query.sn });
    });
  }
  // questions.map((item, index) => {
  //   item.title = index + 1;
  // });
};

const emitFun = {
  move: () => {
    saveQueItem();
  },
  copy: (item) => {
    saveQueItem(null, [item]);
  },
  delete: () => {
    emit('getActiveQuestion', { id: null });
    saveQueItem();
  },
  // 右下角操作
  setting: (item) => {
    saveQueItem(null, [item]);
  },
  logics: (item) => {
    saveQueItem(questionInfo.value.logics, [item]);
  }
};
// 直接切割 变更为响应式
const updateElement = (newElement) => {
  const index = questionInfo.value.questions.findIndex((q) => q.id === newElement.id);
  if (index !== -1) {
    questionInfo.value.questions.splice(index, 1, newElement);
  }
  saveQueItem(questionInfo.value.logics, [newElement]);
};
</script>
<style scoped lang="scss">
.ml10 {
  margin-left: 5px;
}

.design-create {
  //min-height: calc(100vh);
  //background-color: #e9eef3;
  color: #333;

  ::v-deep .slot-actions {
    & .action-item {
      font-size: 15px;
    }

    & .action-item + .action-item {
      margin-left: 10px;
    }
  }
}
</style>
