<template>
  <div
    ref="courseware"
    class="courseware"
    :style="[
      {
        backgroundImage: background.background_image_url ? `url(${background.background_image_url})` : '',
        backgroundSize: background.background_image_url
          ? `${background.background_position.width}% ${background.background_position.height}%`
          : '',
        backgroundPosition: background.background_image_url
          ? `${background.background_position.left}% ${background.background_position.top}%`
          : '',
      },
    ]"
  >
    <!-- 行 -->
    <template v-for="(row, i) in data.row_list">
      <div v-show="computedRowVisibility(row.row_id)" :key="i" class="row">
        <el-checkbox
          v-if="
            isShowGroup &&
            groupRowList.find(({ row_id, is_pre_same_group }) => row.row_id === row_id && !is_pre_same_group)
          "
          v-model="rowCheckList[row.row_id]"
          :class="['row-checkbox', `${row.row_id}`]"
        />
        <!-- 列 -->
        <template v-for="(col, j) in row.col_list">
          <div :key="j" :class="['col', `col-${i}-${j}`]">
            <!-- 网格 -->
            <template v-for="(grid, k) in col.grid_list">
              <component
                :is="previewComponentList[grid.type]"
                :key="k"
                ref="preview"
                class="grid"
                :content="computedColContent(grid.id)"
                :data-row="i"
                :data-col="j"
                :data-grid="k"
                :data-view-order="computedGridViewOrder(grid.id)"
                :class="[grid.id]"
                :is-mobile="true"
                :data-id="grid.id"
                :style="{
                  gridArea: grid.grid_area,
                }"
              />
            </template>
          </div>
        </template>
      </div>
    </template>
  </div>
</template>

<script>
import { previewComponentList } from '@/views/book/courseware/data/bookType';

export default {
  name: 'MobileCoursewarePreview',
  provide() {
    return {
      getDragStatus: () => false,
      bookInfo: this.bookInfo,
    };
  },
  props: {
    data: {
      type: Object,
      default: () => ({}),
    },
    background: {
      type: Object,
      default: () => ({}),
    },
    componentList: {
      type: Array,
      required: true,
    },
    canRemark: {
      type: Boolean,
      default: false,
    },
    showRemark: {
      type: Boolean,
      default: false,
    },
    componentRemarkObj: {
      type: Object,
      default: () => ({}),
    },
    groupRowList: {
      type: Array,
      default: () => [],
    },
    isShowGroup: {
      type: Boolean,
      default: false,
    },
    groupShowAll: {
      type: Boolean,
      default: true,
    },
  },
  data() {
    return {
      previewComponentList,
      bookInfo: {
        theme_color: '',
      },
      showMenu: false,
      divPosition: {
        left: 0,
        top: 0,
      }, // courseware盒子原始距离页面顶部和左边的距离
      menuPosition: { x: 0, y: 0, select_node: '' }, // 用于存储菜单的位置
      componentId: '', // 添加批注的组件id
      rowCheckList: {},
    };
  },
  watch: {
    groupRowList: {
      handler(val) {
        if (!val) return;
        this.rowCheckList = val
          .filter(({ is_pre_same_group }) => !is_pre_same_group)
          .reduce((acc, row) => {
            acc[row.row_id] = false;
            return acc;
          }, {});
      },
    },
  },
  mounted() {
    const element = this.$refs.courseware;
    const rect = element.getBoundingClientRect();
    this.divPosition = {
      left: rect.left,
      top: rect.top,
    };
  },
  methods: {
    /**
     * 计算组件内容
     * @param {string} id 组件id
     * @returns {string} 组件内容
     */
    computedColContent(id) {
      if (!id) return '';
      return this.componentList.find((item) => item.component_id === id)?.content || '';
    },
    getMultipleColStyle(i) {
      let row = this.data.row_list[i];
      let col = row.col_list;
      if (col.length <= 1) {
        return {
          gridTemplateColumns: '100fr',
        };
      }
      let gridTemplateColumns = row.width_list.join(' ');

      return {
        gridAutoFlow: 'column',
        gridTemplateColumns,
        gridTemplateRows: 'auto',
      };
    },
    /**
     * 计算行的可见性
     * @params {string} rowId 行的ID
     * @returns {boolean} 行是否可见
     */
    computedRowVisibility(rowId) {
      if (this.groupShowAll) return true;
      let { row_id, is_pre_same_group } = this.groupRowList.find(({ row_id }) => row_id === rowId);
      if (is_pre_same_group) {
        const index = this.groupRowList.findIndex(({ row_id }) => row_id === rowId);
        if (index === -1) return false;
        for (let i = index - 1; i >= 0; i--) {
          if (!this.groupRowList[i].is_pre_same_group) {
            return this.rowCheckList[this.groupRowList[i].row_id];
          }
        }
        return false;
      }
      return this.rowCheckList[row_id];
    },
    /**
     * 分割整数为多个 1的倍数
     * @param {number} num
     * @param {number} parts
     */
    splitInteger(num, parts) {
      let base = Math.floor(num / parts);
      let arr = Array(parts).fill(base);
      let remainder = num - base * parts;
      for (let i = 0; remainder > 0; i = (i + 1) % parts) {
        arr[i] += 1;
        remainder -= 1;
      }
      return arr;
    },
    computedColStyle(col) {
      const grid = col.grid_list || [];
      if (!grid.length) {
        return {
          width: col.width,
          gridTemplateAreas: '',
          gridTemplateColumns: '',
          gridTemplateRows: '',
        };
      }

      // 一次遍历完成按行分组，并记录最大列数所在行
      let maxCol = 0;
      let curMaxRow = 0;
      const rowMap = new Map();
      grid.forEach((item) => {
        if (!rowMap.has(item.row)) {
          rowMap.set(item.row, []);
        }
        const rowItems = rowMap.get(item.row);
        rowItems.push(item);
        if (rowItems.length > maxCol) {
          maxCol = rowItems.length;
          curMaxRow = item.row;
        }
      });

      // 计算 grid_template_areas
      let gridTemplateAreas = '';
      const sortedRows = Array.from(rowMap.keys()).sort((a, b) => a - b);
      sortedRows.forEach((row) => {
        const rowItems = rowMap.get(row);
        const rowAreas = [];
        if (row === curMaxRow) {
          rowItems.forEach(({ grid_area }) => {
            rowAreas.push(`${grid_area}`);
          });
        } else {
          const needNum = maxCol - rowItems.length;
          const splitList = rowItems.length > 1 ? this.splitInteger(needNum, rowItems.length) : [];
          rowItems.forEach(({ grid_area }, index) => {
            if (rowItems.length === 1) {
              rowAreas.push(` ${grid_area} `.repeat(needNum + 1));
              return;
            }
            const repeatNum = splitList[index] + 1;
            rowAreas.push(splitList[index] === 0 ? ` ${grid_area} ` : ` ${grid_area} `.repeat(repeatNum));
          });
        }
        gridTemplateAreas += `'${rowAreas.join(' ')}' `;
      });

      // 计算 grid_template_columns
      const maxRowItems = rowMap.get(curMaxRow) || [];
      const gridTemplateColumns = maxRowItems.map(({ width }) => width).join(' ');

      // 移动端高度统一使用 auto
      const gridTemplateRows = `${sortedRows.map(() => 'auto').join(' ')} `;

      return {
        width: col.width,
        gridTemplateAreas,
        gridTemplateColumns,
        gridTemplateRows,
      };
    },
    /**
     * 查找子组件
     * @param {string} id 组件的唯一标识符
     * @returns {Promise<HTMLElement|null>} 返回找到的子组件或 null
     */
    async findChildComponentByKey(id) {
      await this.$nextTick();
      return this.$refs.preview.find((child) => child.dataset.id === id);
    },
    /**
     * 模拟回答
     * @param {boolean} isJudgingRightWrong 是否判断对错
     * @param {boolean} isShowRightAnswer 是否显示正确答案
     * @param {boolean} disabled 是否禁用
     */
    simulateAnswer(isJudgingRightWrong, isShowRightAnswer, disabled = true) {
      this.$refs.preview.forEach((item) => {
        item.showAnswer(isJudgingRightWrong, isShowRightAnswer, null, disabled);
      });
    },
    /**
     * 获取网格 id，是第几行第几列第几个网格，通过 data.row_list 计算
     * @param {string} id 网格 id
     * @returns {number} 网格的显示顺序
     */
    computedGridViewOrder(id) {
      let rowIndex = -1;
      let colIndex = -1;
      let gridIndex = -1;

      this.data.row_list.forEach((row, i) => {
        row.col_list.forEach((col, j) => {
          col.grid_list.forEach((grid, k) => {
            if (grid.id === id) {
              rowIndex = i;
              colIndex = j;
              gridIndex = k;
            }
          });
        });
      });

      let order = 0;
      // 计算前几行的网格数量
      if (rowIndex > 0) {
        for (let i = 0; i < rowIndex; i++) {
          this.data.row_list[i].col_list.forEach((col) => {
            order += col.grid_list.length;
          });
        }
      }
      // 计算当前行前几列的网格数量
      if (colIndex > 0) {
        for (let j = 0; j < colIndex; j++) {
          order += this.data.row_list[rowIndex].col_list[j].grid_list.length;
        }
      }
      // 加上当前列前面的网格数量
      order += gridIndex + 1;
      return order;
    },
  },
};
</script>

<style lang="scss">
.courseware {
  position: relative;
  display: flex;
  flex-direction: column;
  row-gap: 6px;
  width: 100%;
  height: 100%;
  min-height: 500px;
  padding: 2%;
  background-color: #fff;
  background-repeat: no-repeat;
  border-bottom-right-radius: 12px;
  border-bottom-left-radius: 12px;

  .row {
    display: flex;
    flex-direction: column;
    gap: 16px;

    .col {
      display: flex;
      flex-direction: column;
      gap: 16px;
      overflow: hidden;

      .grid {
        width: 100%;
      }

      .main {
        .option-list {
          flex-direction: column !important;
        }
      }
    }

    .row-checkbox {
      position: absolute;
      left: 4px;
    }
  }

  .custom-context-menu,
  .remark-info {
    position: absolute;
    z-index: 999;
    display: flex;
    gap: 3px;
    align-items: center;
    font-size: 14px;
    cursor: pointer;
  }

  .custom-context-menu {
    padding-left: 30px;
    background: url('../../../../assets/icon-publish.png') left center no-repeat;
    background-size: 24px;
  }
}
</style>
