<script setup lang="ts">
import { debounce } from '@/hooks'
import { cleanVersions } from '@/api/subject/config'
import subjectApi from '@/api/subject/subject'
import hud from '@/utils/hud'
import { book_select_practice, book_select_video } from '.'
import type { BookVersion, TextBook } from '@/api/subject/subject'

const props = withDefaults(
  defineProps<{
    modelValue: boolean
    type: number
    subjectId: any
    gradeId?: any
    stageId?: any
    lockedBookIds?: any[]
    showBookIds?: any
  }>(),
  {
    modelValue: false,
    type: book_select_practice,
    subjectId: '',
    lockedBookIds: [] as any,
    showBookIds: [] as any,
  },
)

const emits = defineEmits(['update:modelValue', 'update:type', 'ok'])

const OSS_URL = import.meta.env.VITE_OSS_URL
const textbookOptionSelectedTr = `${OSS_URL}/urm/textbook_option_selected_tr.svg`

const show = computed({
  get() {
    return props.modelValue
  },
  set(newVal) {
    emits('update:modelValue', newVal)
  },
})

const versionList = ref([] as BookVersion[]) // 包含教材
const version = ref({} as BookVersion)
const loading = ref(false)

function normalizeVersions(source: any): BookVersion[] {
  const rows = Array.isArray(source?.rows)
    ? source.rows
    : Array.isArray(source?.data?.rows)
      ? source.data.rows
      : Array.isArray(source)
        ? source
        : []

  if (!rows.length) return []

  // 旧结构：版本列表（每个版本里有 textBookVoList）
  if (rows.some((item: any) => Array.isArray(item?.textBookVoList))) {
    for (const item of rows) {
      if (!Array.isArray(item.textBookVoList)) item.textBookVoList = []
    }
    return rows as BookVersion[]
  }

  // 新结构：教材平铺列表，按版本字段聚合为旧结构
  const versionMap = new Map<any, BookVersion>()
  for (const book of rows) {
    const versionId =
      book.bookVersionId ??
      book.versionId ??
      book.versionBaseId ??
      book.bookVersionName ??
      'default'
    if (!versionMap.has(versionId)) {
      versionMap.set(versionId, {
        id: book.bookVersionId ?? book.versionId ?? versionId,
        baseId: book.versionBaseId ?? book.bookVersionId ?? book.versionId ?? versionId,
        name: book.bookVersionName || book.versionName || '教材版本',
        shortName: book.bookVersionName || book.versionName || '教材版本',
        delFlag: 0,
        textBookVoList: [],
        clean: {} as any,
      } as BookVersion)
    }
    versionMap.get(versionId)?.textBookVoList.push(book)
  }
  return Array.from(versionMap.values())
}

async function initVersion(resource = 0) {
  loading.value = true
  setTimeout(async () => {
    try {
      const versionRes = await subjectApi.getSubjectTextBookVersion({
        subjectId: props.subjectId,
        gradeId: props.gradeId,
        stageId: props.stageId,
        resource,
      })
      const versions = normalizeVersions(versionRes)
      cleanVersions(versions)

      // 设置书本是否允许选择
      for (const version of versions) {
        for (const book of version.textBookVoList || []) {
          book.locked = props.lockedBookIds?.includes(book.id)
        }
      }
      versionList.value = versions

      // 确保触发filter的改变
      filter.value = undefined as any
      await nextTick()
      // 设置过滤
      if (props.showBookIds?.length) {
        filter.value = filter_show
      } else {
        filter.value = filter_all
      }
    } catch (err) {
      console.error(err)
      versionList.value = []
      showVersionList.value = []
      textbookList.value = []
    } finally {
      loading.value = false
    }
  }, 100)
}

function changeVersion(data: BookVersion) {
  if (!data) {
    version.value = {} as BookVersion
    textbookList.value = []
    return
  }
  version.value = data
  const books = data.textBookVoList || []
  if (filter.value === filter_show) {
    textbookList.value = books.filter(book => props.showBookIds.includes(book.id))
  } else {
    textbookList.value = books
  }
}

const textbookList = ref([] as TextBook[])
const selectTextbook = ref({} as TextBook) // 单选

function onSelect(data: any) {
  if (data.locked && props.type !== 3) return
  selectTextbook.value = data
}

async function onOk() {
  if (!selectTextbook.value.id) {
    hud.error('请选择教材')
    return
  }
  emits('ok', toRaw(selectTextbook.value))
}

const debounceOk = debounce(onOk, 1000)

async function onOpen() {
  version.value = {} as BookVersion
  selectTextbook.value = {} as TextBook

  if (props.type === book_select_practice) {
    // 选择教材
    initVersion()
  } else if (props.type === book_select_video) {
    initVersion(1)
  }
}

// 显示的版本
const showVersionList = ref([] as BookVersion[])

// 筛书本
const filter_all = '1'
const filter_show = '2'
const filter = ref('')
const filterOptions = [
  {
    label: '仅显示特定教材',
    value: filter_show,
  },
  {
    label: '显示全部教材',
    value: filter_all,
  },
]

function filterChange() {
  if (filter.value === filter_show) {
    showVersionList.value = versionList.value.filter(v => {
      return (v.textBookVoList || []).some(book => props.showBookIds.includes(book.id))
    })
  } else {
    showVersionList.value = versionList.value
  }
  changeVersion(showVersionList.value[0])
}

// 监听过滤器
watch(() => filter.value, filterChange)
</script>

<template>
  <el-dialog
    v-model="show"
    class="book-select"
    :show-close="false"
    destroy-on-close
    align-center
    v-bind="$attrs"
    @open="onOpen"
  >
    <board-bg class="body">
      <div class="content">
        <div class="content-select">
          <div class="tips">
            <LineFont text="选择教材" size="48" space="20" />
            <div class="fixed-right">
              <select-tab
                v-if="showBookIds.length"
                v-model="filter"
                :data-list="filterOptions"
                type="small"
              />
            </div>
          </div>
          <div class="main">
            <Empty v-if="loading" type="loading" />
            <template v-else>
              <el-scrollbar class="filter-list">
                <div
                  v-for="item in showVersionList"
                  :key="item.id"
                  :class="{
                    item: true,
                    'is-active': version.id === item.id,
                  }"
                  :style="version.id === item.id ? `background:${item.clean.color.bgColor};` : ''"
                  @click="changeVersion(item)"
                >
                  <span class="name">{{ item.clean.name }}</span>
                  <span
                    v-for="tag in item.clean.tags"
                    :key="tag"
                    :style="{
                      background: item.clean.color.color,
                    }"
                    class="tag"
                  >
                    {{ tag }}
                  </span>
                </div>
              </el-scrollbar>
              <el-scrollbar class="list">
                <div
                  v-for="book in textbookList"
                  :key="book.id"
                  :class="{
                    item: true,
                    'is-check': book.locked && type !== book_select_video,
                    'is-select':
                      (!book.locked || type === book_select_video) && selectTextbook.id === book.id,
                  }"
                  @click="onSelect(book)"
                >
                  <div
                    class="item-cover hidden_scroll"
                    :style="{
                      background: book.clean.color.bgColor,
                    }"
                  >
                    <LineFont
                      :text="book.clean.name"
                      :size="book.clean.name.length > 10 ? 28 : 34"
                      :border="book.clean.name.length > 10 ? 6 : 8"
                    />
                    <Icon
                      v-if="book.locked && type !== book_select_video"
                      class="select-icon"
                      name="textbook_select"
                      size="70"
                    />
                    <!-- <div
                      v-if="book.locked && type !== 3"
                      class="item-progress"
                      :style="{
                        background: book.clean.color.color,
                      }"
                    >
                      {{ (book.progress / 100).toFixed(0) }}%
                    </div> -->
                    <img
                      v-if="
                        (!book.locked || type === book_select_video) &&
                        selectTextbook.id === book.id
                      "
                      :src="textbookOptionSelectedTr"
                    />
                    <div class="tags">
                      <span
                        v-for="tag in book.clean.tags"
                        :key="tag"
                        :style="`background-color: ${book.clean.color.color}`"
                        class="tag"
                        >{{ tag }}</span
                      >
                    </div>
                  </div>
                </div>
              </el-scrollbar>
            </template>
          </div>
        </div>
      </div>
      <div
        :class="{
          footer: true,
          'is-suspension': type !== 0,
        }"
      >
        <mj-button width="386" type="warn" height="108" size="48" @click="debounceOk"
          >确认</mj-button
        >
      </div>
    </board-bg>
  </el-dialog>
</template>

<style lang="scss">
.book-select {
  width: 1650px;
  height: 92vh;
  margin: 0;
  padding: 0;
  background: transparent;
  box-shadow: none;

  .el-dialog__header {
    display: none;
  }

  .el-dialog__body {
    height: 100%;
    padding: 0;
    position: relative;

    .body {
      padding: 0;
      height: 100%;
      background-color: #e6f5fe;
      .content {
        width: 100%;
        .tips {
          top: 0;
          left: 0;
          width: 100%;
          height: auto;
          padding: 4.33vh 0 $space-3;
          display: flex;
          flex-wrap: wrap;
          align-items: center;
          justify-content: center;
          font-family: $font-text;
          font-size: $font-size-7;
          color: $font-tag-color;
          .small-tip {
            width: 100%;
            font-family: OPPOSans;
            text-align: center;
            font-size: $font-size-7;
            line-height: 1.5em;
            margin-top: $space-1_h;
          }

          .fixed-right {
            position: absolute;
            top: 4.8vh;
            right: 86px;
          }
        }
        &-select {
          width: 100%;
          .main {
            width: 100%;
            height: 63.17vh;
            padding: 1.67vh $space-4 0;
            display: flex;
            flex-wrap: wrap;
            gap: 40px;

            .filter-list {
              padding-left: 36px;
              width: 330px;

              &::after {
                content: '';
                position: absolute;
                bottom: 0;
                left: 20px;
                right: 0;
                height: 0.83vh;
                background: linear-gradient(to bottom, transparent, rgba(212, 238, 253, 0.5));
                pointer-events: none; /* 避免遮挡点击 */
              }

              .item {
                font-size: 2.83vh;
                color: #666;
                padding: 1.67vh 0;
                padding-left: 25px;
                cursor: pointer;
                border-radius: 1.67vh;
                margin: 0.83vh 0;
                display: flex;
                gap: 10px;
                flex-wrap: wrap;
                position: relative;

                &:not(:last-child):after {
                  content: '';
                  position: absolute;
                  bottom: 0;
                  left: 20px;
                  right: 0;
                  width: 80%;
                  height: 0.08vh;
                  background: rgba(0, 0, 0, 0.1);
                  pointer-events: none; /* 避免遮挡点击 */
                }

                &.is-active {
                  background-color: #8ee8fa;
                  color: #000;
                  &::after {
                    content: none;
                  }
                }

                .tag {
                  background-color: $book-tag-bg;
                  color: $book-tag-color;
                  font-size: 2vh;
                  line-height: 2.83vh;
                  padding: 0.42vh 10px;
                  border-radius: 0.83vh;
                  text-align: center;
                }
              }
            }

            .filter {
              width: 100%;
              height: 4.67vh;
              display: flex;
              transition: all 0.3s ease;
              position: relative;
              &::after {
                position: absolute;
                bottom: -1.33vh;
                content: '';
                display: block;
                width: 100%;
                height: 1.33vh;
                background: linear-gradient(
                  180.09deg,
                  #c2ecff -21.76%,
                  rgba(223, 245, 255, 0) 99.91%
                );
              }
              .filter-drawer {
                padding-top: 0.33vh;
                margin: 0 $space-3;
                .x-icon {
                  transition: all 0.3s ease-in-out;
                }
              }

              &.is-expand {
                height: 18.67vh;
                .el-scrollbar__wrap {
                  .el-scrollbar__view {
                    flex-wrap: wrap;
                  }
                }
                .filter-drawer {
                  .x-icon {
                    transform: rotate(180deg);
                  }
                }
              }
            }
            .list {
              flex: 1;
              overflow: hidden;
              // display: flex;
              // flex-wrap: wrap;

              .el-scrollbar__wrap {
                width: 100%;
                .el-scrollbar__view {
                  display: flex;
                  flex-wrap: wrap;
                  gap: 4.33vh;
                }
              }

              .item {
                width: 20vh;
                height: auto;
                position: relative;
                z-index: 1;

                .tags {
                  width: 100%;
                  position: absolute;
                  left: 5px;
                  bottom: 1vh;
                  display: flex;
                  flex-wrap: wrap;
                  justify-content: center;
                  gap: 5px;

                  .tag {
                    color: $book-tag-color;
                    font-size: 1.5vh;
                    line-height: 2vh;
                    padding: 0.25vh 10px;
                    border-radius: 1.5vh;
                    text-align: center;
                    font-weight: bold;
                  }
                }

                &-cover {
                  width: 100%;
                  height: 25vh;
                  background: #ffacf0;
                  border: 0.67vh solid transparent;
                  border-radius: $radius-5;
                  display: flex;
                  align-items: center;
                  justify-content: center;
                  padding: 0 8px;
                  text-align: center;
                  box-shadow: 0 0.33vh 0.33vh 0 rgba(0, 0, 0, 0.25);

                  .x-line-font {
                    letter-spacing: 10px;
                    font-family: $font-text;
                  }
                }
                &-desc {
                  text-align: center;
                  font-size: $font-size-1;
                  line-height: 1.5em;
                  margin-top: $space-2_h;
                  padding: 0 8px;
                }
                &-progress {
                  min-width: 78px;
                  max-width: 120px;
                  height: 3.67vh;
                  line-height: 3.67vh;
                  color: #fff;
                  font-family: $font-text;
                  font-size: 1.67vh;
                  background: #fc5ec9;
                  position: absolute;
                  top: 0;
                  left: 0;
                  border-radius: 1.67vh 0 1.67vh 0;
                }
              }

              .is-check {
                position: relative;
                .item-cover {
                  position: relative;
                  border: none;

                  &::after {
                    display: block;
                    content: '';
                    width: 100%;
                    height: 100%;
                    background: rgba(0, 0, 0, 0.45);
                    position: absolute;
                    left: 0;
                    border-radius: $radius-5;
                  }
                }
                .select-icon {
                  position: absolute;
                  z-index: 1;
                }
              }

              .is-select {
                position: relative;
                .item-cover {
                  border-color: #fff;
                  img {
                    width: 80px;
                    height: 4vh;
                    position: absolute;
                    top: 0.5vh;
                    right: 6px;
                  }
                }
              }
            }
          }
        }
      }
      .footer {
        text-align: center;
        z-index: 3;
        padding-top: 1.5vh;
        // .x-button {
        //   margin-right: $space-4;
        //   &:last-child {
        //     margin-right: 0;
        //   }
        // }
        // &.is-suspension {
        //   position: absolute;
        //   bottom: 4.17vh;
        //   left: 50%;
        //   transform: translateX(-50%);
        // }
      }
    }
  }
}
</style>
