<template>
  <div class="text-subtitle-1 font-weight-bold my-3 d-flex align-center">
    <v-icon start :icon="mdiSchool" />
    子檔資料示範
  </div>

  <div v-if="isMobile" class="d-flex flex-column ga-3">
    <v-card
      v-for="semester in semesters"
      :key="semester.id"
      class="cursor-pointer"
      :class="{ 'border-opacity-100': selectedSemesterId === semester.id }"
      :color="selectedSemesterId === semester.id ? 'primary' : undefined"
      variant="outlined"
      @click="$emit('select', semester.id)"
    >
      <v-card-text class="pa-4">
        <div class="d-flex align-start justify-space-between ga-3">
          <div>
            <div class="text-body-1 font-weight-bold">{{ semester.semesterName }}</div>
            <div class="text-caption text-medium-emphasis">點擊查看課程與成績</div>
          </div>
          <v-icon size="small" :icon="mdiChevronRight" />
        </div>

        <div class="d-flex flex-wrap ga-2 mt-3">
          <v-chip color="primary" size="small" variant="tonal">平均 {{ semester.average }}</v-chip>
          <v-chip size="small" variant="tonal">排名 {{ semester.rank }}</v-chip>
          <v-chip size="small" variant="tonal">課程 {{ semester.courses.length }}</v-chip>
        </div>
      </v-card-text>
    </v-card>
  </div>

  <div v-else class="flex-grow-1" style="min-height: 0">
    <div class="d-flex flex-column ga-3 overflow-y-auto pr-1 h-100">
      <v-expansion-panels>
        <v-expansion-panel v-for="semester in semesters" :key="semester.id">
          <v-expansion-panel-title color="background">
            <div class="d-flex align-center ga-3 w-100 pr-2">
              <span class="font-weight-medium">{{ semester.semesterName }}</span>
            </div>
          </v-expansion-panel-title>
          <v-expansion-panel-text>
            <div class="d-flex align-center mb-2">
              <span class="text-subtitle-1 font-weight-bold text-medium-emphasis">課程列表</span>
              <v-spacer />
              <v-btn
                v-if="!isFormReadonly"
                color="primary"
                :disabled="isFormLocked"
                :prepend-icon="mdiPlus"
                size="small"
                variant="tonal"
                @click="$emit('add-course', semester.id)"
              >
                加入課程
              </v-btn>
            </div>

            <v-table class="border rounded" density="compact" fixed-header>
              <thead>
                <tr>
                  <th class="cursor-pointer" width="50%" @click="toggleSort(semester.id, 'name')">
                    <div class="d-flex align-center ga-1">
                      <span>課程名稱</span>
                      <v-icon size="small" :icon="getSortIcon(semester.id, 'name')" />
                    </div>
                  </th>
                  <th class="cursor-pointer" @click="toggleSort(semester.id, 'credits')">
                    <div class="d-flex align-center ga-1">
                      <span>學分</span>
                      <v-icon size="small" :icon="getSortIcon(semester.id, 'credits')" />
                    </div>
                  </th>
                  <th class="cursor-pointer" @click="toggleSort(semester.id, 'score')">
                    <div class="d-flex align-center ga-1">
                      <span>分數</span>
                      <v-icon size="small" :icon="getSortIcon(semester.id, 'score')" />
                    </div>
                  </th>
                  <th v-if="!isFormReadonly" width="52"></th>
                </tr>
              </thead>
              <tbody>
                <tr
                  v-for="{ course, originalIndex } in getSortedCourses(semester)"
                  :key="`${semester.id}-${originalIndex}`"
                >
                  <td class="py-0">{{ course.name }}</td>
                  <td class="align-top py-0">
                    <span v-if="isFormReadonly">{{ course.credits }}</span>
                    <v-text-field
                      v-else
                      :aria-label="`${semester.semesterName} ${course.name} 學分`"
                      density="compact"
                      :disabled="isFormLocked"
                      hide-details
                      hide-spin-buttons
                      :model-value="course.credits"
                      :name="`semester-${semester.id}-course-${originalIndex}-credits`"
                      type="number"
                      variant="outlined"
                      @update:model-value="
                        (value) =>
                          $emit('update-course', semester.id, originalIndex, {
                            credits: Number(value) || 0,
                          })
                      "
                    />
                  </td>
                  <td class="align-top py-0">
                    <span v-if="isFormReadonly">{{ course.score }}</span>
                    <v-text-field
                      v-else
                      :aria-label="`${semester.semesterName} ${course.name} 分數`"
                      density="compact"
                      :disabled="isFormLocked"
                      hide-details
                      hide-spin-buttons
                      :model-value="course.score"
                      :name="`semester-${semester.id}-course-${originalIndex}-score`"
                      type="number"
                      variant="outlined"
                      @update:model-value="
                        (value) =>
                          $emit('update-course', semester.id, originalIndex, {
                            score: Number(value) || 0,
                          })
                      "
                    />
                  </td>
                  <td v-if="!isFormReadonly" class="px-1 text-center">
                    <v-btn
                      color="error"
                      :disabled="isFormLocked"
                      :icon="mdiDeleteOutline"
                      size="small"
                      variant="text"
                      @click="$emit('delete-course', semester.id, originalIndex, course.name)"
                    />
                  </td>
                </tr>
                <tr v-if="semester.courses.length === 0">
                  <td
                    class="text-center text-medium-emphasis py-6"
                    :colspan="isFormReadonly ? 3 : 4"
                  >
                    <div class="d-flex flex-column align-center ga-2">
                      <v-icon color="medium-emphasis" size="24" :icon="mdiBookOpenOutline" />
                      <span class="text-caption">尚無課程，點擊「加入課程」新增</span>
                    </div>
                  </td>
                </tr>
              </tbody>
            </v-table>
          </v-expansion-panel-text>
        </v-expansion-panel>
      </v-expansion-panels>
    </div>
  </div>

  <div
    v-if="semesters.length === 0"
    class="text-caption text-center py-6 text-medium-emphasis border border-dashed rounded"
  >
    尚無學期資料
  </div>
</template>

<script setup lang="ts">
import type { CourseRecord, SemesterRecord } from '@/stores/semesters'
import {
  mdiArrowDown,
  mdiArrowUp,
  mdiBookOpenOutline,
  mdiChevronRight,
  mdiDeleteOutline,
  mdiPlus,
  mdiSchool,
  mdiSwapVertical,
} from '@mdi/js'
import { ref } from 'vue'

type CourseSortKey = 'name' | 'credits' | 'score'

interface CourseSortState {
  key: CourseSortKey
  order: 'asc' | 'desc'
}

interface SortedCourseRow {
  course: CourseRecord
  originalIndex: number
}

defineProps<{
  semesters: SemesterRecord[]
  isMobile: boolean
  isFormReadonly: boolean
  isFormLocked: boolean
  selectedSemesterId: number | null
}>()

defineEmits<{
  (event: 'select', semesterId: number): void
  (event: 'add-course', semesterId: number): void
  (
    event: 'update-course',
    semesterId: number,
    courseIndex: number,
    payload: Partial<CourseRecord>
  ): void
  (event: 'delete-course', semesterId: number, courseIndex: number, courseName: string): void
}>()

const semesterSortStates = ref<Record<number, CourseSortState>>({})

const getSortState = (semesterId: number) => semesterSortStates.value[semesterId]

function toggleSort(semesterId: number, key: CourseSortKey) {
  const current = getSortState(semesterId)

  semesterSortStates.value[semesterId] =
    current?.key === key
      ? {
          key,
          order: current.order === 'asc' ? 'desc' : 'asc',
        }
      : {
          key,
          order: 'asc',
        }
}

function getSortIcon(semesterId: number, key: CourseSortKey) {
  const current = getSortState(semesterId)

  if (current?.key !== key) return mdiSwapVertical
  return current.order === 'asc' ? mdiArrowUp : mdiArrowDown
}

function compareCourseValue(left: CourseRecord, right: CourseRecord, key: CourseSortKey) {
  if (key === 'name') return left.name.localeCompare(right.name, 'zh-Hant')
  return left[key] - right[key]
}

function getSortedCourses(semester: SemesterRecord): SortedCourseRow[] {
  const rows = semester.courses.map((course, originalIndex) => ({
    course,
    originalIndex,
  }))
  const sortState = getSortState(semester.id)

  if (!sortState) return rows

  return [...rows].sort((left, right) => {
    const result = compareCourseValue(left.course, right.course, sortState.key)

    if (result === 0) return left.originalIndex - right.originalIndex
    return sortState.order === 'asc' ? result : -result
  })
}
</script>
