<!-- 弹窗列表 -->
<template>
  <div class="musicwikiList">
    <div class="headCon">
      <div class="headLeft">
        <img class="tipImg" :src="tipImgObj[type]" alt="" />
        <div class="title">{{ titObj[type] }}</div>
      </div>
      <div class="headright">
        <img @click="emits('close')" class="closeBtn" src="../../cloudCoachElement/cloudCoachList/imgs/close.png" alt="" />
      </div>
    </div>
    <div class="content">
      <div class="tabTools">
        <div class="tabBox">
          <div class="tabCon" ref="tabConDom" @wheel.prevent="handleMousewheelTabCon">
            <div
              class="tab"
              @click="handleResourcesTypeChange(item)"
              :class="{ active: item.id === queryData.resourcesType }"
              v-for="item in resourcesTypeOption"
              :key="item.id"
            >
              {{ item.name }}
            </div>
          </div>
          <div v-if="horizontalScrollbar" class="tabChangeCon">
            <div class="tabChangeLeft" @click="handleScrollTabCon(-150)"></div>
            <div class="tabChangeRight" @click="handleScrollTabCon(150)"></div>
          </div>
        </div>
        <div class="query">
          <Input :placeholder="'请输入搜索关键词'" v-model:value="queryData.keyword" clearable @enter="handleQuery" @clear="handleQuery">
            <template #prefix>
              <img class="img" src="../../cloudCoachElement/cloudCoachList/imgs/query.png" alt="" />
            </template>
            <template #suffix>
              <div class="queryBtn" @click="handleQuery">搜索</div>
            </template>
          </Input>
        </div>
      </div>
      <div class="musicListCon">
        <div class="queryFrom">
          <div class="queryFromList" v-if="classificationOption.length">
            <div class="tit">分类：</div>
            <div class="queryFromCon">
              <div
                @click="handleClassificationChange(item)"
                v-for="item in classificationOption"
                :key="item.id"
                :class="['queryTip', queryData.classification === item.id && 'active']"
              >
                {{ item.name }}
              </div>
            </div>
          </div>
          <div class="queryFromList" v-if="typeOption.length">
            <div class="tit">类型：</div>
            <div class="queryFromCon">
              <template v-for="item in typeOption">
                <div
                  :class="['queryTip', queryData.type.id === item.id && 'active']"
                  @click="handleTypeChange(item)"
                  v-if="item.childrenList.length === 0"
                  :key="item.id"
                >
                  {{ item.name }}
                </div>
                <Popover v-model:value="item.isExpand" trigger="mouseenter" :placement="'bottom-start'" v-else :offset="-4" :key="item.id + '_'">
                  <template #content>
                    <PopoverMenuItem
                      @click="
                        () => {
                          handleTypeChange(row)
                          item.isExpand = false
                        }
                      "
                      v-for="row in item.childrenList"
                      :key="row.id"
                      :active="row.id === queryData.type.id"
                      >{{ row.name }}</PopoverMenuItem
                    >
                  </template>
                  <div class="queryTip" :class="{ hoverActive: isActiveSubjectPop(item) }">
                    <div>{{ queryData.type.id !== item.id && isActiveSubjectPop(item) ? queryData.type.name : item.name }}</div>
                    <img src="../../cloudCoachElement/cloudCoachList/imgs/jt.png" alt="" />
                  </div>
                </Popover>
              </template>
            </div>
          </div>
        </div>
        <div class="musicListConBox" v-loading="loading">
          <div class="musicList" :class="{ empty: !musicList.length && !loading }">
            <template v-if="musicList.length && !loading">
              <musicListVue :musicList="musicList" @handle-add="handleAdd" @handle-preview="handlePreview" v-if="type === 'MUSIC'" />
              <musicianListVue :musicList="musicList" @handle-add="handleAdd" @handle-preview="handlePreview" v-else-if="type === 'MUSICIAN'" />
              <instrumentListVue :musicList="musicList" @handle-add="handleAdd" @handle-preview="handlePreview" v-else />
            </template>
            <Empty v-if="!musicList.length && !loading" />
          </div>
          <div class="pagination" v-show="musicList.length">
            <el-pagination
              layout="prev, pager, next"
              :default-page-size="queryData.rows"
              :current-page="queryData.page"
              @current-change="handleCurrentChange"
              :total="queryData.total"
            />
          </div>
        </div>
      </div>
    </div>
  </div>
  <Modal
    :contentStyle="{
      width: '86%',
      minWidth: '1200px',
      height: '90%',
      boxShadow: '0px 2px 10px 0px rgba(0,0,0,0.08)',
      borderRadius: '16px',
      border: '1px solid #DEDEDE',
      padding: '0'
    }"
    v-model:visible="previewMusicObjVisible"
  >
    <musicPreview
      :musicObj="previewMusicObj"
      :type="type"
      @close="
        () => {
          previewMusicObjVisible = false
        }
      "
    />
  </Modal>
</template>

<script setup lang="ts">
import { getKnowledgeWikiCategoryType, getKnowledgeWikiPage } from "@/api/musicResources"
import { ElLoading, ElPagination } from "element-plus"
import Input from "@/components/Input.vue"
import Popover from "@/components/Popover.vue"
import PopoverMenuItem from "@/components/PopoverMenuItem.vue"
import Empty from "@/components/Empty"
import Modal from "@/components/Modal.vue"
import { httpAjax } from "@/plugins/httpAjax"
import { reactive, ref, nextTick } from "vue"
import musicPreview from "./musicPreview.vue"
import mqjsImg from "@/views/Editor/CanvasTool/imgs/mqjs.png"
import yyjImg from "@/views/Editor/CanvasTool/imgs/yyj.png"
import yqbkImg from "@/views/Editor/CanvasTool/imgs/yqbk.png"
import { CODE_ERR_CANCELED } from "@/libs/auth"
import musicListVue from "./components/musicList.vue"
import musicianListVue from "./components/musicianList.vue"
import instrumentListVue from "./components/instrumentList.vue"
import { type pptContentType } from "@/views/components/element/musicResourcesElement"

const props = defineProps<{
  type: Exclude<pptContentType, "THEORY">
}>()

const emits = defineEmits<{
  (event: "update", item: Record<string, any>, type: Exclude<pptContentType, "THEORY">): void
  (event: "close"): void
}>()

const titObj = {
  MUSIC: "名曲鉴赏",
  INSTRUMENT: "乐器百科",
  MUSICIAN: "音乐家"
}
const tipImgObj = {
  MUSIC: mqjsImg,
  INSTRUMENT: yqbkImg,
  MUSICIAN: yyjImg
}

const musicList = ref<any[]>([])
const loading = ref(true)
const vLoading = ElLoading.directive
// 资源类型
const resourcesTypeOption = ref<any[]>([])
const classificationOption = ref<any[]>([])
const typeOption = ref<any[]>([])

// 不同类型 每页显示不同的数量
const pageRowObj = {
  MUSIC: 21,
  INSTRUMENT: 24,
  MUSICIAN: 24
}

const queryData = reactive({
  page: 1,
  rows: pageRowObj[props.type],
  total: 0,
  keyword: "",
  resourcesType: "",
  classification: "",
  type: {
    id: "",
    name: ""
  }
})

getQueryList()
function getQueryList() {
  httpAjax(getKnowledgeWikiCategoryType, props.type).then(res => {
    if (res.code === 200) {
      resourcesTypeOption.value = res.data?.rows || []
      // 初始化第三层数据
      resourcesTypeOption.value.map(item => {
        item.childrenList?.map((itemVal: any) => {
          itemVal.childrenList?.map((itemV: any) => {
            if (itemV.childrenList?.length > 0) {
              itemV.childrenList = [
                {
                  id: itemV.id,
                  name: "全部",
                  childrenList: []
                },
                ...itemV.childrenList
              ]
              Object.assign(itemV, { isExpand: ref(false) })
            }
          })
        })
      })
      handleResourcesTypeChange(resourcesTypeOption.value[0])
      // 判断 有没有滚动条
      nextTick(() => {
        hasHorizontalScrollbar()
      })
    }
  })
}

function handleResourcesTypeChange(item: Record<string, any>) {
  queryData.resourcesType = item.id
  classificationOption.value = []
  queryData.classification = ""
  typeOption.value = []
  queryData.type = {
    id: "",
    name: ""
  }
  if (item.childrenList?.length) {
    classificationOption.value = [
      {
        id: item.id,
        name: "全部",
        childrenList: []
      },
      ...item.childrenList
    ]
    queryData.classification = item.id
    handleClassificationChange(classificationOption.value[0])
    return
  }
  handleQuery()
}

function handleClassificationChange(item: Record<string, any>) {
  queryData.classification = item.id
  typeOption.value = []
  queryData.type = {
    id: "",
    name: ""
  }
  if (item.childrenList?.length) {
    typeOption.value = [
      {
        id: item.id,
        name: "全部",
        childrenList: []
      },
      ...item.childrenList
    ]
    handleTypeChange(typeOption.value[0])
    return
  }
  handleQuery()
}

function handleTypeChange(item: Record<string, any>) {
  queryData.type = {
    id: item.id,
    name: item.name
  }
  handleQuery()
}
function isActiveSubjectPop(item: any) {
  return item.childrenList.some((i: any) => {
    return i.id === queryData.type.id
  })
}

function handleCurrentChange(e: number) {
  queryData.page = e
  handleGetQuery()
}
function handleQuery() {
  queryData.page = 1
  queryData.rows = pageRowObj[props.type]
  handleGetQuery()
}

let controller: AbortController
function handleGetQuery() {
  loading.value = true
  let { page, rows, keyword, resourcesType, classification, type } = queryData
  const wikiCategoryId = type.id || classification || resourcesType
  const params = {
    keyword,
    page,
    rows,
    type: props.type,
    wikiCategoryId
  }
  if (controller) {
    controller.abort()
  }
  controller = new AbortController()
  httpAjax(getKnowledgeWikiPage, params, controller).then(res => {
    // 自己关闭的时候不取消加载
    if (res.code === CODE_ERR_CANCELED) {
      return
    }
    if (res.code === 200) {
      musicList.value = res.data.rows.map((item: any) => {
        item.highName = highlightedText(item.name, queryData.keyword)
        return item
      })
      queryData.total = res.data.total
    }
    loading.value = false
  })
}
const highlightedText = (text: string, query: string) => {
  if (!text) {
    return ""
  }
  if (!query) {
    return text
  }
  const regex = new RegExp(`(${query})`, "gi")
  return text.replace(regex, '<span class="highlighted">$1</span>')
}

/* 预览 */
const previewMusicObjVisible = ref(false)
const previewMusicObj = ref<Record<string, any>>({
  id: "",
  name: ""
})
function handlePreview(item: Record<string, any>) {
  previewMusicObj.value.id = item.id
  previewMusicObj.value.name = item.name
  previewMusicObjVisible.value = true
}
function handleAdd(item: Record<string, any>) {
  emits("update", item, props.type)
}

// 横向拖动
const tabConDom = ref<HTMLElement>()
const horizontalScrollbar = ref(false)
function handleMousewheelTabCon(event: WheelEvent) {
  handleScrollTabCon(event.deltaY)
}
function handleScrollTabCon(num: number) {
  tabConDom.value?.scrollBy(num, 0)
}
function hasHorizontalScrollbar() {
  if (tabConDom.value) {
    horizontalScrollbar.value = tabConDom.value.scrollWidth > tabConDom.value.clientWidth
  }
}
</script>

<style lang="scss" scoped>
.musicwikiList {
  width: 100%;
  height: 100%;
  .headCon {
    width: 100%;
    height: 64px;
    border-bottom: 1px solid #eaeaea;
    display: flex;
    justify-content: space-between;
    align-items: center;
    .headLeft {
      margin-left: 30px;
      display: flex;
      align-items: center;
      .tipImg {
        width: 24px;
        height: 24px;
      }
      .title {
        font-weight: 600;
        font-size: 18px;
        color: #131415;
        margin-left: 8px;
      }
    }
    .headright {
      margin-right: 30px;
      display: flex;
      align-items: center;
      .closeBtn {
        width: 24px;
        height: 24px;
        cursor: pointer;
        &:hover {
          opacity: 0.8;
        }
      }
    }
  }
  .content {
    width: 100%;
    height: calc(100% - 64px);
    display: flex;
    flex-direction: column;
    .tabTools {
      height: 72px;
      width: 100%;
      padding: 18px 30px;
      display: flex;
      justify-content: space-between;
      align-items: center;
      .tabBox {
        display: flex;
        margin-right: 20px;
        .tabCon {
          display: flex;
          overflow-x: auto;
          &::-webkit-scrollbar {
            display: none;
          }
          .tab {
            flex-shrink: 0;
            margin-right: 32px;
            font-weight: 400;
            font-size: 16px;
            color: #8b8d98;
            line-height: 22px;
            cursor: pointer;
            &:hover {
              opacity: 0.8;
            }
            &:last-child {
              margin-right: 0;
            }
            &.active {
              font-weight: 600;
              color: #131415;
              position: relative;
              &::after {
                content: "";
                position: absolute;
                width: 100%;
                height: 10px;
                background: linear-gradient(90deg, #77bbff 0%, rgba(163, 231, 255, 0.22) 100%);
                bottom: 0;
                left: 0;
                z-index: -1;
              }
            }
          }
        }
        .tabChangeCon {
          margin-left: 16px;
          flex-shrink: 0;
          display: flex;
          .tabChangeLeft {
            width: 24px;
            height: 24px;
            background: url("./imgs/btnLeft.png") no-repeat;
            background-size: 100% 100%;
            cursor: pointer;
            &:hover {
              opacity: 0.8;
            }
          }
          .tabChangeRight {
            margin-left: 16px;
            width: 24px;
            height: 24px;
            background: url("./imgs/btnRight..png") no-repeat;
            background-size: 100% 100%;
            cursor: pointer;
            &:hover {
              opacity: 0.8;
            }
          }
        }
      }
      .query {
        width: 400px;
        height: 36px;
        flex-shrink: 0;
        &::v-deep(.input) {
          align-items: center;
          padding: 0 3px 0 12px;
          border-radius: 18px;
          height: 100%;
          &:not(.disabled):hover,
          &.focused {
            .img {
              opacity: 1;
            }
            .queryBtn {
              opacity: 1;
            }
          }
          input {
            font-size: 14px;
          }
          .img {
            width: 16px;
            height: 16px;
            opacity: 0.4;
          }
          .queryBtn {
            width: 60px;
            height: 30px;
            background: #198cfe;
            border-radius: 16px;
            font-weight: 500;
            font-size: 14px;
            color: #ffffff;
            line-height: 30px;
            text-align: center;
            opacity: 0.4;
            cursor: pointer;
            &:hover {
              opacity: 0.8 !important;
            }
          }
        }
      }
    }
    .musicListCon {
      width: 100%;
      flex-grow: 1;
      overflow: hidden;
      display: flex;
      flex-direction: column;
      .queryFrom {
        flex-shrink: 0;
        padding: 0 30px;
        .queryFromList {
          display: flex;
          margin-bottom: 4px;
          .tit {
            flex-shrink: 0;
            font-weight: 500;
            font-size: 14px;
            color: #131415;
            line-height: 32px;
            margin-right: 16px;
          }
          .queryFromCon {
            display: flex;
            flex-wrap: wrap;
            .queryTip {
              margin: 0 16px 12px 0;
              font-weight: 400;
              font-size: 14px;
              color: rgba(0, 0, 0, 0.6);
              line-height: 20px;
              padding: 6px 16px;
              background: #f5f6fa;
              border-radius: 6px;
              cursor: pointer;
              display: flex;
              align-items: center;
              & > img {
                width: 7px;
                height: 4px;
                margin-left: 6px;
              }
              &:hover {
                background: #e8e9ed;
                color: #5d5d5e;
                > img {
                  transform: rotate(180deg);
                }
              }
              &.active {
                background: #d2ecff;
                color: rgba(0, 0, 0, 1);
              }
              &.hoverActive {
                background: #d2ecff;
                color: rgba(0, 0, 0, 1);
              }
            }
          }
        }
      }
      .isExpand {
        flex-shrink: 0;
        margin-bottom: 12px;
        cursor: pointer;
        display: flex;
        justify-content: center;
        font-weight: 400;
        font-size: 14px;
        color: #198cfe;
        line-height: 20px;
        align-items: center;
        &:hover {
          opacity: 0.8;
        }
        &.active > img {
          transform: rotate(0deg);
        }
        & > img {
          transform: rotate(180deg);
          margin-left: 4px;
          width: 10px;
          height: 10px;
        }
      }
      .musicListConBox {
        flex-grow: 1;
        overflow: hidden;
        .musicList {
          padding: 4px 0;
          height: calc(100% - 60px);
          overflow: auto;
          &.empty {
            display: flex;
            justify-content: center;
            align-items: center;
          }
        }
        .pagination {
          padding: 0 30px;
          display: flex;
          justify-content: flex-end;
          align-items: center;
          height: 60px;
        }
      }
    }
  }
}
</style>
