<script setup lang="ts">
import { get } from '#/api/http'

type Book = {
  courseId?: any
  gradeId?: any
  id: any
  name: any
  title: any
  versionId?: any
}
defineOptions({ name: 'TextbookMultiSelect' })
const props = withDefaults(
  defineProps<{
    modelValue?: boolean
    selectedBooks?: Book[]
  }>(),
  {
    modelValue: false,
    selectedBooks: [] as any,
  },
)
const emits = defineEmits(['update:modelValue', 'ok'])
const selectedBookMap = {} as Record<any, Book>
const show = computed({
  get() {
    return props.modelValue
  },
  set(newVal) {
    emits('update:modelValue', newVal)
    stageId.value = undefined
    if (newVal) {
      loadMyTextbooks()
      loadStages()
    }
  },
})

async function loadMyTextbooks() {
  const res = await get<any>('/xkw/textbook/myTextbooks')
  const list = extractList(res)
  bookIds.value = list.map((item: any) => {
    const book: Book = {
      id: item.textbookId,
      name: item.textbookName,
      versionId: item.versionId,
      courseId: item.courseId,
      gradeId: item.gradeId,
      title: `${item.courseName}·${item.textbookName}`,
    }
    selectedBookMap[item.textbookId] = book
    textbookCache[item.textbookId] = {
      ...book,
      volume: item.textbookName,
    }
    courseNameMap[item.courseId] = item.courseName
    return item.textbookId
  })
}

function extractList(res: any) {
  return Array.isArray(res) ? res : res?.rows || []
}

// 阶段
const stageList = ref<any[]>([])
const stageId = ref(undefined as any)

async function loadStages() {
  const res = await get<any>('/xkw/stage/list', { status: 0, size: -1 })
  stageList.value = extractList(res)
  if (stageList.value.length > 0) {
    nextTick(() => {
      stageId.value = stageList.value[0].id
    })
  }
}

function handleStage(id: any) {
  stageId.value = id
}

// 课程
const courseList = ref<any[]>([])
const courseId = ref(undefined as any)
const courseNameMap = {} as Record<any, string>

async function stageChange() {
  courseId.value = undefined
  courseList.value = []
  if (!stageId.value) return
  const res = await get<any>('/xkw/course/list', {
    stageId: stageId.value,
    status: 0,
    size: -1,
  })
  courseList.value = extractList(res)
  for (const c of courseList.value) {
    courseNameMap[c.id] = c.shortName || c.name
  }
  if (courseList.value.length > 0) {
    nextTick(() => {
      courseId.value = courseList.value[0].id
    })
  }
}

function handleCourse(id: any) {
  courseId.value = id
}

// 教材版本
const versionList = ref<any[]>([])
const versionId = ref(undefined as any)

async function courseChange() {
  versionId.value = undefined
  versionList.value = []
  if (!courseId.value) return
  const res = await get<any>('/xkw/textbookVersion/list', {
    courseId: courseId.value,
    status: 0,
    size: -1,
  })
  versionList.value = extractList(res)
  if (versionList.value.length > 0) {
    nextTick(() => {
      versionId.value = versionList.value[0].id
    })
  }
}

function handleVersion(id: any) {
  versionId.value = id
}

// 教材
const textbookList = ref<any[]>([])
const textbookCache = {} as Record<any, any>

async function versionChange() {
  textbookList.value = []
  if (!versionId.value) return
  const res = await get<any>('/xkw/textbook/list', {
    versionId: versionId.value,
    status: 0,
    size: -1,
  })
  textbookList.value = extractList(res)
  for (const book of textbookList.value) {
    textbookCache[book.id] = book
  }
}

// 有选中书籍的教材版本id
const selectedVersionIdMap = ref({} as any)

// 监控
watch(() => stageId.value, stageChange)
watch(() => courseId.value, courseChange)
watch(() => versionId.value, versionChange)

const bookIds = ref([] as any[])

// 所有选中的教材
const books = computed<Book[]>(() => {
  selectedVersionIdMap.value = {} as any
  const list = [] as Book[]
  for (const id of bookIds.value) {
    const cached = textbookCache[id]
    let dstBook: Book
    if (cached) {
      dstBook = {
        id,
        name: cached.name,
        versionId: cached.versionId,
        courseId: cached.courseId,
        gradeId: cached.gradeId,
        title: `${courseNameMap[cached.courseId] || ''}·${cached.name}`,
      }
    } else {
      const book = selectedBookMap[id] as Book
      dstBook = {
        id,
        name: book?.name || id,
        versionId: book?.versionId,
        courseId: book?.courseId,
        gradeId: book?.gradeId,
        title: book?.title || book?.name || id,
      }
    }
    list.push(dstBook)
    if (dstBook.versionId) {
      selectedVersionIdMap.value[dstBook.versionId] = true
    }
  }
  return list
})

function ok() {
  emits('ok', toRaw(books.value))
}
</script>

<template>
  <mj-modal
    v-model="show"
    :options="{
      title: '教材选择',
      width: '86%',
      height: '80%',
      showFooter: true,
      showCancelButton: true,
      showConfirmButton: true,
    }"
    @confirm="ok"
  >
    <div class="textbook-multi-select">
      <div class="header">
        <span class="title">
          <span>
            <span>共选中{{ bookIds.length }}本教材</span>
            <span v-if="bookIds.length > 0">：</span>
          </span>
          <span class="book-name" :key="book.id" v-for="book in books">{{
            book.title
          }}</span>
        </span>

        <el-button type="danger" @click="bookIds = []">清除所有</el-button>
      </div>
      <div class="section">
        <span class="title">阶段</span>
        <div class="items">
          <div
            v-for="item in stageList"
            :key="item.id"
            class="item"
            :class="{ active: stageId === item.id }"
            @click="handleStage(item.id)"
          >
            {{ item.name }}
          </div>
        </div>
      </div>
      <hr />
      <div class="section">
        <span class="title">课程</span>
        <div class="items">
          <div
            v-for="item in courseList"
            :key="item.id"
            class="item"
            :class="{ active: courseId === item.id }"
            @click="handleCourse(item.id)"
          >
            {{ item.shortName || item.name }}
          </div>
        </div>
      </div>
      <hr />
      <div class="section">
        <span class="title">教材版本</span>
        <div class="items">
          <div
            v-for="item in versionList"
            :key="item.id"
            class="item"
            :class="{
              selected: selectedVersionIdMap[item.id],
              active: versionId === item.id,
            }"
            @click="handleVersion(item.id)"
          >
            {{ item.name }}
          </div>
        </div>
      </div>
      <hr />
      <div class="section">
        <span class="title">教材</span>
        <div class="items">
          <mj-check-group
            v-model="bookIds"
            :options="textbookList"
            label-key="volume"
            value-key="id"
          />
        </div>
      </div>
    </div>
  </mj-modal>
</template>

<style lang="scss" scoped>
$title_fz: 18px;
$item_fz: 16px;

@mixin selected {
  color: #409eff;
  border-bottom: 1px solid #409eff;
}

@mixin active {
  color: #fff;
  background-color: #409eff;
  border-radius: 4px;
}

.textbook-multi-select {
  padding: 0 24px;

  .header {
    display: flex;
    gap: 20px;
    align-items: center;
    font-size: $item_fz;

    .title {
      display: flex;
      flex-wrap: wrap;
      gap: 15px;
      align-items: center;
    }

    .book-name {
      @include selected;
    }
  }

  .section {
    display: flex;
    padding: 20px 0;

    .title {
      margin-right: 20px;
      font-size: $title_fz;
      font-weight: bold;
    }

    .items {
      display: flex;
      flex: 1;
      flex-wrap: wrap;
      gap: 20px;
      font-size: $item_fz;

      .item {
        padding: 2px 5px;
        cursor: pointer;

        &.active {
          @include active;
        }

        &.selected:not(.active) {
          @include selected;
        }
      }
    }
  }
}
</style>
