<template>
  <div class="question-group-struct">
    <div class="struct-set">
      <el-checkbox v-model="useClassify" @change="setChange"
        >指定文件夹抽题</el-checkbox
      >
      <el-checkbox v-model="useDifficult" @change="setChange"
        >按难度抽题</el-checkbox
      >
      <el-checkbox v-model="useProperty" @change="setChange"
        >按课程属性抽题</el-checkbox
      >
      <el-select
        v-if="useProperty"
        v-model="curCoursePropertyId"
        class="margin-left-10"
        size="small"
        @change="buildDataList"
      >
        <el-option
          v-for="item in propertyInfo"
          :key="item.id"
          :label="item.name"
          :value="item.id"
        ></el-option>
      </el-select>
    </div>
    <div v-if="!USE_NONE_SET" class="struct-box">
      <div v-if="useClassify" class="struct-folder">
        <el-tree
          ref="folderTree"
          class="folder-tree"
          :data="classifyTree"
          node-key="id"
          default-expand-all
          :expand-on-click-node="false"
          check-on-click-node
          show-checkbox
          check-strictly
          :props="treeProps"
          @check-change="checkChange"
        ></el-tree>
      </div>
      <div class="struct-prop">
        <el-table
          :data="tableData"
          :tree-props="tableTreeProps"
          row-key="id"
          border
          max-height="400"
        >
          <el-table-column label="分类" prop="name">
            <template slot-scope="scope">
              <i
                v-if="scope.row.isClassify"
                class="icon icon-files-act margin-right-5"
              ></i>

              <span
                v-if="scope.row.isClassify && scope.row.id === '0'"
                class="inline-middle"
                >根目录</span
              >
              <span v-else class="inline-middle">{{ scope.row.name }}</span>
            </template>
          </el-table-column>
          <el-table-column
            v-if="!useDifficult || USE_ONLY_DIFFICULT"
            label="数量"
            width="150"
          >
            <template slot-scope="scope">
              <el-input-number
                v-model="scope.row.selectCount"
                size="mini"
                :step="1"
                :min="0"
                :max="scope.row.questionCount"
                :controls="false"
                :precision="0"
                step-strictly
                @change="selectCountChange"
              ></el-input-number>
              <span class="inline-middle">/ {{ scope.row.questionCount }}</span>
            </template>
          </el-table-column>
          <el-table-column
            v-for="(dinfo, dindex) in difficultDistributeInfo"
            v-else
            :key="dindex"
            :label="dinfo"
            width="150"
          >
            <template
              v-if="
                scope.row.difficultDistributeInfo &&
                scope.row.difficultDistributeInfo.length &&
                !(scope.row.useClassify && useProperty)
              "
              slot-scope="scope"
            >
              <el-input-number
                v-model="scope.row.difficultDistributeInfo[dindex].selectCount"
                size="mini"
                :step="1"
                :min="0"
                :max="scope.row.difficultDistributeInfo[dindex].questionCount"
                :controls="false"
                :precision="0"
                step-strictly
                @change="selectCountChange"
              ></el-input-number>
              <span class="inline-middle"
                >/
                {{
                  scope.row.difficultDistributeInfo[dindex].questionCount
                }}</span
              >
            </template>
          </el-table-column>
        </el-table>
      </div>
    </div>
  </div>
</template>

<script>
import { questionGroupStructListApi } from "../api";
import { classifyTreeApi } from "../../question/api";
import { calcSum, deepCopy } from "@/plugins/utils";

export default {
  name: "QuestionGroupStruct",
  props: {
    filterData: {
      type: Object,
      default() {
        return {
          courseId: "",
          sourceDetailId: "",
        };
      },
    },
    dataSource: {
      type: Object,
      default: null,
    },
  },
  data() {
    return {
      useClassify: false,
      useDifficult: false,
      useProperty: false,
      selectedFolderIds: [],
      classifyTree: [
        {
          id: 0,
          parent: null,
          name: "根目录",
          children: [],
        },
      ],
      treeProps: {
        label: "name",
      },
      originList: [],
      dataList: [],
      tableData: [],
      tableTreeProps: {
        children: "propertyDistributeInfo",
      },
      difficultDistributeInfo: [],
      curCoursePropertyId: "",
      propertyInfo: [],
      sourceDataMap: {},
    };
  },
  computed: {
    USE_ONLY_DIFFICULT() {
      return !this.useClassify && this.useDifficult && !this.useProperty;
    },
    USE_ONLY_PROPERTY() {
      return !this.useClassify && !this.useDifficult && this.useProperty;
    },
    USE_NONE_SET() {
      return !this.useClassify && !this.useDifficult && !this.useProperty;
    },
    SOURCE_REVIEW() {
      return !!this.dataSource;
    },
  },
  watch: {
    filterData: {
      deep: true,
      handler(val, oldval) {
        if (JSON.stringify(val) !== JSON.stringify(oldval)) {
          this.resetDataList();
        }
      },
    },
  },
  async mounted() {
    if (this.dataSource) {
      this.parseSourceDataMap();
      this.useProperty = !!this.dataSource.useProperty;
      this.useClassify = !!this.dataSource.useClassify;
      this.useDifficult = !!this.dataSource.useDifficult;
      if (this.useClassify)
        this.selectedFolderIds = this.dataSource.classifyIdList || [];
    }
    await this.resetDataList();
    await this.getClassifyTree();

    if (this.selectedFolderIds.length) {
      this.$nextTick(() => {
        this.$refs.folderTree.setCheckedKeys(this.selectedFolderIds);
      });
    }
  },
  methods: {
    setChange() {
      if (!this.useClassify) this.selectedFolderIds = [];
      this.resetDataList();
    },
    checkChange() {
      this.selectedFolderIds = this.$refs.folderTree.getCheckedKeys();
      this.resetDataList();
    },
    async getClassifyTree() {
      const res = await classifyTreeApi();
      this.classifyTree[0].children = res.data || [];
    },
    async resetDataList() {
      if (!this.useClassify && !this.useDifficult && !this.useProperty) {
        this.originList = [];
        this.dataList = [];
        this.tableData = [];
        return;
      }
      const res = await this.getOriginList().catch(() => {});
      if (!res) return;

      if (this.useProperty) {
        this.parsePropertyInfo();
      }
      this.buildDataList();
    },
    async getOriginList() {
      if (this.useClassify && !this.selectedFolderIds.length) {
        this.$message.error("请选择选择文件夹！");
        return Promise.reject();
      }
      let data = {
        ...this.filterData,
        useDifficult: this.useDifficult,
        useProperty: this.useProperty,
      };
      if (this.useClassify && this.selectedFolderIds.length)
        data.classifyIdList = this.selectedFolderIds.join();

      const res = await questionGroupStructListApi(data);
      this.originList = res.data || [];
      return true;
    },
    parsePropertyInfo() {
      if (!this.useProperty) {
        this.propertyInfo = [];
        return;
      }
      let coursePropertyIds = [],
        propertyInfo = [];
      this.originList.forEach((item) => {
        if (
          !item.coursePropertyDistributeInfo ||
          !item.coursePropertyDistributeInfo.length
        )
          return;

        item.coursePropertyDistributeInfo.forEach((prop) => {
          if (coursePropertyIds.includes(prop.coursePropertyId)) return;
          coursePropertyIds.push(prop.coursePropertyId);
          propertyInfo.push({
            id: prop.coursePropertyId,
            name: prop.coursePropertyName,
          });
        });
      });
      this.propertyInfo = propertyInfo;

      if (!propertyInfo.length) {
        this.curCourseProp = {};
        return;
      }

      const curCourseProp = propertyInfo.find(
        (item) => item.coursePropertyId === this.curCoursePropertyId
      );
      if (!curCourseProp) {
        this.curCoursePropertyId = propertyInfo[0].id;
      }
    },
    buildDataList() {
      let _this = this;
      function buildClassifyData(data) {
        let cpreInfo = data.classifyId + "";
        let classifyData = {
          id: cpreInfo,
          name: data.classifyName,
          classifyId: data.classifyId,
          classifyName: data.classifyName,
          isClassify: true,
          questionCount: data.questionCount,
          selectCount: _this.gerSourceData(cpreInfo),
          difficultDistributeInfo: [],
        };
        if (
          data.difficultDistributeInfo &&
          data.difficultDistributeInfo.length
        ) {
          classifyData.difficultDistributeInfo = parseQuestionDistributeInfo(
            data.difficultDistributeInfo,
            cpreInfo
          );
        }
        if (
          !data.coursePropertyDistributeInfo ||
          !data.coursePropertyDistributeInfo.length
        )
          return classifyData;

        const curCourseProp = data.coursePropertyDistributeInfo.find(
          (item) => item.coursePropertyId === _this.curCoursePropertyId
        );
        if (!curCourseProp) {
          return classifyData;
        }

        classifyData.propertyDistributeInfo =
          curCourseProp.propertyDistributeInfo.map((item) =>
            parsePropertyData(item, `${cpreInfo}_${_this.curCoursePropertyId}`)
          );

        classifyData.propertyDistributeInfo = filterPropertyData(
          classifyData.propertyDistributeInfo
        );

        return classifyData;
      }

      function parseQuestionDistributeInfo(data, preInfo) {
        if (!_this.difficultDistributeInfo.length) {
          _this.difficultDistributeInfo = data.map(
            (item) => item.difficultLevel
          );
        }
        return data.map((item) => {
          return {
            ...item,
            selectCount: _this.gerSourceData(
              `${preInfo}_${item.difficultLevel}`
            ),
          };
        });
      }

      function parsePropertyData(data, parentId) {
        const propId = `${parentId}_${data.propertyId}`;
        let propData = {
          id: propId,
          name: data.propertyName,
          propertyId: data.propertyId,
          propertyName: data.propertyName,
          questionCount: data.questionCount,
          selectCount: _this.gerSourceData(propId),
          difficultDistributeInfo: null,
        };
        if (
          data.difficultDistributeInfo &&
          data.difficultDistributeInfo.length
        ) {
          propData.difficultDistributeInfo = parseQuestionDistributeInfo(
            data.difficultDistributeInfo,
            propId
          );
        }

        if (data.propertyDistributeInfo && data.propertyDistributeInfo.length) {
          propData.propertyDistributeInfo = data.propertyDistributeInfo.map(
            (item) => parsePropertyData(item, propId)
          );
        }
        return propData;
      }

      function filterPropertyData(propertyDistributeInfo) {
        // 只处理两级属性
        let pDistributeInfo = propertyDistributeInfo.map((data) => {
          if (
            data.propertyDistributeInfo &&
            data.propertyDistributeInfo.length
          ) {
            data.propertyDistributeInfo = data.propertyDistributeInfo.filter(
              (item) => item.questionCount
            );
          }
          return data;
        });
        pDistributeInfo = pDistributeInfo.filter(
          (data) =>
            data.propertyDistributeInfo && data.propertyDistributeInfo.length
        );
        return pDistributeInfo;
      }

      this.dataList = this.originList.map((item) => buildClassifyData(item));
      this.tableData = this.dataList;

      if (this.USE_ONLY_DIFFICULT) {
        this.tableData = this.dataList[0].difficultDistributeInfo;
        this.tableData = this.tableData.map((item) => {
          let nitem = { ...item };
          nitem.id = item.difficultLevel;
          nitem.name = item.difficultLevel;
          return nitem;
        });
        this.selectCountChange();
        return;
      }
      if (this.useClassify && !this.useProperty) {
        this.tableData = this.dataList.map((item) => {
          let nitem = { ...item };
          nitem.propertyDistributeInfo = null;
          return nitem;
        });
        this.selectCountChange();
        return;
      }
      if (!this.useClassify && this.useProperty) {
        this.tableData = this.dataList[0].propertyDistributeInfo;
        this.selectCountChange();
        return;
      }

      this.selectCountChange();
    },
    getTotalQuestionCount() {
      let questionCount = 0;

      if (this.USE_ONLY_DIFFICULT) {
        questionCount = calcSum(
          this.tableData.map((item) => item.selectCount || 0)
        );
        return questionCount;
      }

      let _this = this;
      function getCount(data) {
        let count = 0;
        if (_this.useDifficult) {
          if (data.difficultDistributeInfo) {
            count = calcSum(
              data.difficultDistributeInfo.map((item) => item.selectCount || 0)
            );
          }
        } else {
          count = data.selectCount || 0;
        }

        return count;
      }

      this.tableData.forEach((item) => {
        questionCount += getCount(item);

        if (this.useProperty && item.propertyDistributeInfo) {
          item.propertyDistributeInfo.forEach((pItem) => {
            questionCount += getCount(pItem);
            if (pItem.propertyDistributeInfo) {
              pItem.propertyDistributeInfo.forEach((spItem) => {
                questionCount += getCount(spItem);
              });
            }
          });
        }
      });

      return questionCount;
    },
    selectCountChange() {
      this.$emit("count-change", this.getTotalQuestionCount());
    },
    getDataList() {
      let dataList = deepCopy(this.dataList);
      let structInfo = {
        classifyIdList: this.useClassify ? this.selectedFolderIds : [],
        questionDistributeInfo: null,
        questionCount: this.getTotalQuestionCount(),
        useClassify: this.useClassify,
        useDifficult: this.useDifficult,
        useProperty: this.useProperty,
        curCoursePropertyId: this.curCoursePropertyId,
      };

      if (this.USE_ONLY_DIFFICULT) {
        dataList[0].difficultDistributeInfo = this.tableData.map((item) => {
          return {
            difficultLevel: item.difficultLevel,
            questionCount: item.questionCount,
            selectCount: item.selectCount,
          };
        });
        structInfo.propertyDistributeInfo = dataList;
        return structInfo;
      } else if (this.useClassify && !this.useProperty) {
        dataList = deepCopy(this.tableData);
        structInfo.propertyDistributeInfo = dataList;
        return structInfo;
      } else if (!this.useClassify && this.useProperty) {
        dataList[0].propertyDistributeInfo = this.tableData;
      }

      const curCourseProp = this.propertyInfo.find(
        (item) => item.id === this.curCoursePropertyId
      );
      dataList = dataList.map((item) => {
        item.coursePropertyDistributeInfo = [
          {
            coursePropertyId: curCourseProp.id,
            coursePropertyName: curCourseProp.name,
            propertyDistributeInfo: item.propertyDistributeInfo,
          },
        ];
        return item;
      });

      structInfo.propertyDistributeInfo = dataList;
      return structInfo;
    },
    // source relate
    gerSourceData(k) {
      return this.sourceDataMap[k] || undefined;
    },
    parseSourceDataMap() {
      let sourceDataMap = {};

      function parseDifficultMap(difficultDistributeInfo, preInfo) {
        if (!difficultDistributeInfo || !difficultDistributeInfo.length) return;

        difficultDistributeInfo.forEach((d) => {
          if (d.selectCount)
            sourceDataMap[`${preInfo}_${d.difficultLevel}`] = d.selectCount;
        });
      }

      function parsePropertyMap(propertyDistributeInfo, preInfo) {
        if (!propertyDistributeInfo || !propertyDistributeInfo.length) return;

        propertyDistributeInfo.forEach((pInfo) => {
          let ppreInfo = `${preInfo}_${pInfo.propertyId}`;
          if (pInfo.selectCount) sourceDataMap[ppreInfo] = pInfo.selectCount;
          parseDifficultMap(pInfo.difficultDistributeInfo, ppreInfo);

          parsePropertyMap(pInfo.propertyDistributeInfo, ppreInfo);
        });
      }

      if (
        this.dataSource.questionDistributeInfo &&
        this.dataSource.questionDistributeInfo.length
      ) {
        this.dataSource.questionDistributeInfo.forEach((classifyData) => {
          let cpreInfo = classifyData.classifyId + "";
          if (classifyData.selectCount) {
            sourceDataMap[cpreInfo] = classifyData.selectCount;
          }

          parseDifficultMap(classifyData.difficultDistributeInfo, cpreInfo);
          if (
            classifyData.coursePropertyDistributeInfo &&
            classifyData.coursePropertyDistributeInfo.length
          ) {
            let preInfo = `${cpreInfo}_${classifyData.coursePropertyDistributeInfo[0].coursePropertyId}`;
            parsePropertyMap(
              classifyData.coursePropertyDistributeInfo[0]
                .propertyDistributeInfo,
              preInfo
            );
          }
        });
      }
      this.sourceDataMap = sourceDataMap;
    },
  },
};
</script>
