<template>
  <div class="setting">
    <div class="breadcrumb">
      <ul>
        <li>
          <span class="pointer" @click="$router.push('/')">教材管理</span>
        </li>
        <li>
          <span class="separator">></span>
          <span class="breadcrumb-name">{{ data.name }}</span>
        </li>
      </ul>
    </div>

    <main class="setting-wrapper">
      <div class="basic-info">
        <div class="editor">
          <div class="title">基本信息</div>
          <el-button @click="edit"><SvgIcon icon-class="edit" /> 编辑</el-button>
        </div>
        <el-image :src="data.picture_url" class="cover-image">
          <div slot="error" class="image-slot">
            <i class="el-icon-picture-outline"></i>
          </div>
        </el-image>
        <div class="name">{{ data.name }}</div>
        <div class="brief-introduction">{{ data.description }}</div>
      </div>

      <div class="catalogue-wrapper" :style="{ backgroundColor: isEdit ? 'inherit' : '#fff' }">
        <!-- 显示区域 -->
        <template v-if="!isEdit">
          <div class="catalogue-top">
            <div class="title">目录</div>
            <div class="operation">
              <el-button><SvgIcon icon-class="palette" /> 主色设置</el-button>
              <el-button @click="isEdit = true"><SvgIcon icon-class="edit" /> 编辑目录</el-button>
              <el-button @click="enterPreview"><SvgIcon icon-class="browse" /> 预览</el-button>
            </div>
          </div>

          <div v-for="{ id, name, nodes: children } in nodes" :key="id" class="catalogue">
            <!-- 一级目录 -->
            <div class="catalogue-title">{{ name }}</div>
            <template v-for="item in children">
              <!-- 二级目录或内容 -->
              <div
                :key="item.id"
                :class="['catalogue-item', item.is_leaf_chapter === 'true' ? 'content' : 'subdirectory']"
              >
                <span class="name">{{ item.name }}</span>
                <span class="time">{{ item.time }} {{ item.editor }}</span>
                <span v-if="item.is_leaf_chapter === 'true'" class="edit" @click="editBookContent(item.id)">编辑</span>
              </div>
              <!-- 二级目录的内容 -->
              <template v-if="item.is_leaf_chapter === 'false' && item.nodes?.length > 0">
                <div v-for="li in item.nodes" :key="li.id">
                  <div :class="['catalogue-item', 'children']">
                    <span class="name">{{ li?.name }}</span>
                    <span class="time">{{ li?.time }} {{ li.editor }}</span>
                    <span v-if="li.is_leaf_chapter === 'true'" class="edit" @click="editBookContent(li.id)">编辑</span>
                  </div>
                </div>
              </template>
            </template>
          </div>
        </template>
        <!-- 编辑区域 -->
        <div v-else class="catalogue-edit">
          <div class="catalogue-edit-top">
            <span class="title">编辑目录</span>
            <div class="operation">
              <el-button class="cancel" @click="cancel">取消</el-button>
              <el-button type="primary" @click="complete">完成</el-button>
            </div>
          </div>

          <div class="nodes">
            <template v-for="item in nodes">
              <!-- 一级目录 -->
              <div v-if="item.id === curEditNodeId" :key="item.id" class="nodes-edit">
                <el-input v-model="item.name" placeholder="请输入标题" />
                <el-button type="primary" class="confirm-edit" @click="confirmEditNode(item.id, '', 'false')">
                  确定
                </el-button>
                <el-button @click="cancelEditNode(item.id)">取消</el-button>
              </div>
              <div v-else :key="item.id" class="nodes-item">
                <span class="title">{{ item.name }}</span>
                <span class="operation">
                  <el-dropdown trigger="click">
                    <span class="el-dropdown-link">
                      <SvgIcon icon-class="add-rectangle" />
                    </span>
                    <el-dropdown-menu slot="dropdown">
                      <el-dropdown-item @click.native="createChildCatalogue(item.id, 'false')">子目录</el-dropdown-item>
                      <el-dropdown-item @click.native="createChildCatalogue(item.id, 'true')">内容</el-dropdown-item>
                    </el-dropdown-menu>
                  </el-dropdown>
                  <SvgIcon icon-class="edit" @click="setCurEditNodeId(item.id)" />
                  <SvgIcon icon-class="delete-2" @click="deleteChapter(item.id, 'false')" />
                </span>
              </div>

              <!-- 子目录及内容 -->
              <template v-if="item.is_leaf_chapter === 'false' && item.nodes?.length > 0">
                <!-- 子目录 -->
                <template v-for="li in item.nodes">
                  <div v-if="li.id === curEditNodeId" :key="li.id" class="nodes-edit">
                    <el-input v-model="li.name" placeholder="请输入标题" />
                    <el-button
                      type="primary"
                      class="confirm-edit"
                      @click="confirmEditNode(li.id, item.id, li.is_leaf_chapter)"
                    >
                      确定
                    </el-button>
                    <el-button @click="cancelEditNode(li.id)">取消</el-button>
                  </div>
                  <div
                    v-else
                    :key="li.id"
                    :class="['nodes-item', 'children', li.is_leaf_chapter === 'true' ? '' : 'subdirectory']"
                  >
                    <span class="name">{{ li.name }}</span>
                    <span class="operation">
                      <el-dropdown trigger="click">
                        <span class="el-dropdown-link">
                          <SvgIcon icon-class="add-rectangle" />
                        </span>
                        <el-dropdown-menu slot="dropdown">
                          <el-dropdown-item
                            v-if="li.is_leaf_chapter === 'true'"
                            @click.native="createChildCatalogue(item.id, 'false')"
                            >子目录</el-dropdown-item
                          >
                          <el-dropdown-item
                            @click.native="
                              createChildCatalogue(li.is_leaf_chapter === 'true' ? item.id : li.id, 'true')
                            "
                            >内容</el-dropdown-item
                          >
                        </el-dropdown-menu>
                      </el-dropdown>
                      <SvgIcon icon-class="edit" @click="setCurEditNodeId(li.id)" />
                      <SvgIcon icon-class="delete-2" @click="deleteChapter(li.id, 'false')" />
                    </span>
                  </div>
                  <!-- 内容 -->
                  <template v-if="li.is_leaf_chapter === 'false' && li.nodes?.length > 0">
                    <template v-for="child in li.nodes">
                      <div v-if="child.id === curEditNodeId" :key="child.id" class="nodes-edit">
                        <el-input v-model="child.name" placeholder="请输入标题" />
                        <el-button
                          type="primary"
                          class="confirm-edit"
                          @click="confirmEditNode(child.id, li.id, child.is_leaf_chapter)"
                        >
                          确定
                        </el-button>
                        <el-button @click="cancelEditNode(child.id)">取消</el-button>
                      </div>
                      <div v-else :key="child.id" :class="['nodes-item', 'children']" :style="{ paddingLeft: '32px' }">
                        <span class="name">{{ child.name }}</span>
                        <span class="operation">
                          <el-dropdown trigger="click">
                            <span class="el-dropdown-link">
                              <SvgIcon icon-class="add-rectangle" />
                            </span>
                            <el-dropdown-menu slot="dropdown">
                              <el-dropdown-item
                                @click.native="
                                  createChildCatalogue(child.is_leaf_chapter === 'true' ? li.id : child.id, 'true')
                                "
                                >内容</el-dropdown-item
                              >
                            </el-dropdown-menu>
                          </el-dropdown>
                          <SvgIcon icon-class="edit" @click="setCurEditNodeId(child.id)" />
                          <SvgIcon icon-class="delete-2" @click="deleteChapter(child.id, 'true')" />
                        </span>
                      </div>
                    </template>
                  </template>
                </template>
              </template>
            </template>
          </div>

          <el-button type="primary" @click="createCatalogue"><SvgIcon icon-class="add-rectangle" /> 新建目录</el-button>
        </div>
      </div>
    </main>
  </div>
</template>

<script>
import { GetBook, GetBookChapterStruct, AddChapterToBook, UpdateChapter, DeleteChapter } from '@/api/book';

export default {
  name: 'SettingPage',
  data() {
    return {
      book_id: this.$route.params.book_id,
      isEdit: false, // 是否编辑状态
      curEditNodeId: '', // 当前编辑的节点id
      data: {
        picture_url: '',
        picture_id: '',
        name: '',
        author: '',
        current_price: '',
        original_price: '',
        label_name_list: '',
        type_id: '',
        description: '',
      },
      nodes: [],
      loading: false,
    };
  },
  created() {
    GetBook({ id: this.book_id }).then(({ name, picture_id, picture_url, author, type_id, price, description }) => {
      this.data = {
        name,
        picture_id,
        picture_url,
        author,
        type_id,
        current_price: price,
        original_price: '0.00',
        label_name_list: [],
        description,
      };
    });
    this.getBookChapterStruct();
  },
  methods: {
    edit() {
      this.$router.push({ path: '/book/create', query: { book_id: this.book_id } });
    },
    enterPreview() {
      this.$router.push(`/preview/courseware/${this.book_id}`);
    },
    editBookContent(chapter_id) {
      this.$router.push({ path: '/chapter', query: { chapter_id, book_id: this.book_id } });
    },
    getBookChapterStruct() {
      GetBookChapterStruct({ book_id: this.book_id, node_deep_mode: 0 }).then(({ nodes }) => {
        this.nodes = nodes ?? [];
        this.loading = false;
      });
    },
    /**
     * @description 确认编辑节点
     * @param {string} id 节点id
     * @param {string} parent_id 父节点id
     * @param {string} is_leaf_chapter 是否是内容目录
     */
    confirmEditNode(id, parent_id, is_leaf_chapter) {
      const position = this.findNodeIndexById(this.nodes, id);
      let nodes = this.nodes;
      for (let i = 0; i < position.length - 1; i++) {
        nodes = nodes[position[i]].nodes;
      }
      const name = nodes[position[position.length - 1]].name;
      if (name.length <= 0) {
        this.$message.error('请输入名称');
        // 非编辑状态下删除临时节点
        if (!this.isEdit) {
          this.cancelEditNode(id);
        }
        return;
      }
      if (nodes[position[position.length - 1]]?.temporary) {
        this.addChapterToBook(name, parent_id, is_leaf_chapter);
      } else {
        this.updateChapter(id, name);
      }
    },
    addChapterToBook(name, parent_id, is_leaf) {
      if (this.loading) return;
      this.loading = true;
      AddChapterToBook({ name, book_id: this.book_id, parent_id, is_leaf }).then(() => {
        this.getBookChapterStruct();
      });
    },
    updateChapter(id, name) {
      if (this.loading) return;
      this.loading = true;
      UpdateChapter({ id, name }).then(() => {
        this.getBookChapterStruct();
        this.curEditNodeId = '';
      });
    },
    /**
     * @description 删除目录
     * @param {string} id 目录id
     * @param {'true' | 'false'} is_force_delete 是否强制删除
     */
    deleteChapter(id, is_force_delete) {
      this.$confirm('确定删除该目录吗？', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning',
      })
        .then(() => {
          DeleteChapter({ id, is_force_delete })
            .then(() => {
              this.$message.success('删除成功');
              this.getBookChapterStruct();
            })
            .catch(() => {});
        })
        .catch(() => {});
    },
    createCatalogue() {
      if (this.curEditNodeId) {
        this.cancelEditNode(this.curEditNodeId);
      }
      let id = new Date().getTime();
      const level_index = this.nodes.length;
      this.nodes.push({
        id,
        name: '',
        is_leaf_chapter: 'false',
        level_index,
        temporary: true, // 临时节点
        nodes: [],
      });
      this.curEditNodeId = id;
    },
    /**
     * 创建子目录或内容
     * @param {string} parent_id 父目录id
     * @param {string} is_leaf_chapter 是否是内容目录
     */
    createChildCatalogue(parent_id, is_leaf_chapter) {
      if (this.curEditNodeId) {
        this.cancelEditNode(this.curEditNodeId);
      }
      let id = new Date().getTime();
      let position = this.findNodeIndexById(this.nodes, parent_id);

      let parent = this.nodes;
      for (let i = 0; i < position.length; i++) {
        if (i === position.length - 1) {
          parent = parent[position[i]];
        } else {
          parent = parent[position[i]].nodes;
        }
      }
      const level_index = position.join('-');
      if (!Object.hasOwn(parent, 'nodes')) {
        this.$set(parent, 'nodes', []);
      }
      parent.nodes.push({
        id,
        name: '',
        is_leaf_chapter,
        level_index,
        temporary: true, // 临时节点
        nodes: [],
      });
      this.curEditNodeId = id;
    },
    /**
     * 设置当前编辑节点id
     */
    setCurEditNodeId(id) {
      this.curEditNodeId = id;
    },
    /**
     * 根据节点id查找节点在nodes中的位置
     * @param {array} nodes 节点数组
     * @param {string} id 节点id
     * @param {array} position 节点位置
     */
    findNodeIndexById(nodes, id, position = []) {
      for (let i = 0; i < nodes.length; i++) {
        const node = nodes[i];
        if (node.id === id) {
          position.push(i);
          return position;
        }
        if (node.nodes && node.nodes.length > 0) {
          const childPosition = this.findNodeIndexById(node.nodes, id, [...position, i]);
          if (childPosition.length > 0) {
            return childPosition;
          }
        }
      }
      return [];
    },
    /**
     * 取消编辑节点
     * @param {string} id 节点id
     */
    cancelEditNode(id) {
      const indexArr = this.findNodeIndexById(this.nodes, id);
      let nodes = this.nodes;
      for (let i = 0; i < indexArr.length - 1; i++) {
        nodes = nodes[indexArr[i]].nodes;
      }
      // 删除临时节点
      if (nodes[indexArr[indexArr.length - 1]]?.temporary) {
        nodes.splice(indexArr[indexArr.length - 1], 1);
      }
      this.curEditNodeId = '';
    },
    // 取消编辑
    cancel() {
      this.isEdit = false;
      if (this.curEditNodeId) {
        this.cancelEditNode(this.curEditNodeId);
        this.getBookChapterStruct();
      }
    },
    // 完成编辑
    complete() {
      this.isEdit = false;
      // 如果有正在编辑的节点，先保存
      if (this.curEditNodeId) {
        document.querySelector('.confirm-edit').click();
      }
    },
  },
};
</script>

<style lang="scss" scoped>
%button {
  padding: 7px 15px;

  :deep > span {
    display: flex;
    column-gap: 8px;
    align-items: center;
  }
}

.setting {
  min-height: 100%;
  padding: 8px 24px;

  .breadcrumb {
    position: sticky;
    top: 8px;
    z-index: 1;
    display: flex;
    align-items: center;
    font-size: 14px;

    > ul {
      display: flex;

      li {
        font-weight: 400;
        color: #949494;

        .separator {
          margin: 0 8px;
          color: #c9cdd4;
        }

        &:nth-last-child(1) {
          font-weight: bold;
          color: $font-color;
        }
      }
    }
  }

  .setting-wrapper {
    display: flex;
    column-gap: 24px;
    justify-content: center;
    min-height: calc(100vh - 118px);
    margin-top: 16px;

    .basic-info {
      display: flex;
      flex-direction: column;
      row-gap: 16px;
      width: 276px;
      padding: 24px;
      background-color: #fff;
      border-radius: 4px;

      .editor {
        display: flex;
        align-items: center;
        justify-content: space-between;

        .title {
          font-weight: bold;
          color: #000;
        }

        .el-button {
          @extend %button;
        }
      }

      .cover-image {
        width: 228px;
        height: 320px;
        background-color: #f3f3f3;
        border: 1px solid #e0e0e0;

        :deep .image-slot {
          display: flex;
          align-items: center;
          justify-content: center;
          width: 100%;
          height: 100%;

          i {
            font-size: 40px;
            color: #c0c4cc;
          }
        }
      }

      .name {
        font-weight: bold;
        color: #000;
      }

      .brief-introduction {
        font-size: 14px;
        color: #666;
      }
    }

    .catalogue-wrapper {
      display: flex;
      flex-direction: column;
      row-gap: 16px;
      width: 916px;
      padding: 24px;
      border-radius: 4px;

      .catalogue-top {
        display: flex;
        align-items: center;
        justify-content: space-between;

        .title {
          font-weight: bold;
          color: #000;
        }

        .operation {
          .el-button {
            @extend %button;
          }
        }
      }

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

        &-title {
          padding: 8px 0;
          font-weight: bold;
          color: #000;
        }

        &-item {
          display: flex;
          column-gap: 8px;
          padding: 8px 52px 8px 16px;
          font-size: 14px;
          border-bottom: 1px solid #ebebeb;

          &:hover {
            background-color: #f3f3f3;
          }

          &.subdirectory {
            .name {
              font-weight: bold;
            }
          }

          &.children {
            padding-left: 32px;
          }

          .name {
            flex: 1;
            color: #000;
          }

          .time,
          .edit {
            color: #929292;
          }

          .edit {
            margin-left: 24px;
            cursor: pointer;
          }
        }
      }

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

        &-top {
          display: flex;
          align-items: center;
          justify-content: space-between;

          .title {
            font-weight: bold;
            color: #000;
          }

          .operation {
            .cancel {
              background-color: #e7e7e7;
            }

            .el-button + .el-button {
              margin-left: 16px;
            }
          }
        }

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

          &-edit {
            display: flex;
            column-gap: 8px;

            .el-button + .el-button {
              margin-left: 0;
            }

            .el-input {
              :deep .el-input__inner {
                background-color: #fff;
              }
            }
          }

          &-item {
            display: flex;
            align-items: center;
            justify-content: space-between;
            padding-right: 16px;

            .title {
              flex: 1;
              font-weight: bold;
              color: #000;
            }

            &.children {
              padding: 8px 16px;
              background-color: #fff;

              &:hover {
                background-color: #f3f3f3;
              }

              .name {
                font-size: 14px;
              }

              &.subdirectory {
                .name {
                  font-weight: bold;
                }
              }
            }

            .operation {
              display: flex;
              column-gap: 8px;

              .svg-icon {
                cursor: pointer;
              }
            }
          }
        }
      }
    }
  }
}
</style>
