<script setup lang="ts">
import { computed, onMounted, reactive, ref } from 'vue'
import { Collection, CopyDocument, Plus, Promotion, Refresh, Search } from '@element-plus/icons-vue'
import http, { apiErrorMessage } from '../api/http'
import { useAuthStore } from '../stores/auth'

const auth = useAuthStore()
const loading = ref(false)
const detailLoading = ref(false)
const plans = ref<any[]>([])
const total = ref(0)
const selected = ref<any | null>(null)
const colleges = ref<any[]>([])
const majors = ref<any[]>([])
const grades = ref<number[]>([])
const courses = ref<any[]>([])
const courseGroups = ref<any[]>([])
const planDialog = ref(false)
const moduleDialog = ref(false)
const courseDialog = ref(false)
const cloneDialog = ref(false)
const courseGroupDialog = ref(false)
const courseGroupImportDialog = ref(false)
const detailView = ref<'structure' | 'semester'>('structure')
const editingPlanId = ref('')
const editingPlanStatus = ref('')
const editingModuleId = ref('')
const editingCourseId = ref('')
const activeModuleId = ref('')
const activeCourseGroupId = ref('')
const query = reactive({
  page: 1,
  pageSize: 20,
  keyword: '',
  collegeId: undefined as string | undefined,
  majorId: undefined as string | undefined,
  effectiveGrade: undefined as number | undefined,
  status: undefined as string | undefined,
})
const planForm = reactive<Record<string, any>>({})
const moduleForm = reactive<Record<string, any>>({})
const courseForm = reactive<Record<string, any>>({})
const cloneForm = reactive<Record<string, any>>({})
const courseGroupForm = reactive<Record<string, any>>({})
const courseGroupCourseForm = reactive<Record<string, any>>({})
const courseGroupImportForm = reactive<Record<string, any>>({})

const statusLabels: Record<string, string> = {
  Draft: '草稿',
  Published: '已发布',
  Archived: '已归档',
}
const courseTypeLabels: Record<string, string> = {
  Required: '指定必修',
  Elective: '组内选修',
}
const isCollegeAdmin = computed(() => auth.user?.roles.includes('CollegeAdmin') ?? false)
const canManageCourseGroups = computed(() =>
  auth.user?.roles.some((role) => role === 'SuperAdmin' || role === 'AcademicAdmin') ?? false,
)
const availableMajors = computed(() => majors.value)
const filteredMajors = computed(() =>
  query.collegeId
    ? majors.value.filter((item) => item.collegeId === query.collegeId)
    : majors.value,
)
const availableGrades = computed(() =>
  [...new Set([
    ...grades.value,
    ...plans.value.map((item) => Number(item.effectiveGrade)),
  ])].sort((first, second) => second - first),
)
const maintenanceScope = computed(() =>
  isCollegeAdmin.value
    ? colleges.value[0]?.name ?? '所属学院'
    : '全校各学院',
)
const isDraft = computed(() => selected.value?.status === 'Draft')
const isPublished = computed(() => selected.value?.status === 'Published')
const canEdit = computed(() => isDraft.value || isPublished.value)
const isEditingPublished = computed(() => editingPlanStatus.value === 'Published')
const activeCourseGroup = computed(() =>
  courseGroups.value.find((group) => group.id === activeCourseGroupId.value) ?? null,
)
const importingCourseGroup = computed(() =>
  courseGroups.value.find((group) => group.id === courseGroupImportForm.courseGroupId) ?? null,
)
const configuredCredits = computed(() =>
  selected.value?.modules.reduce(
    (sum: number, module: any) => sum + Number(module.requiredCredits),
    0,
  ) ?? 0,
)
const semesterGroups = computed(() => {
  if (!selected.value) return []

  const courses = selected.value.modules.flatMap((module: any) =>
    module.courses.map((course: any) => ({
      ...course,
      moduleCode: module.code,
      moduleName: module.name,
    })),
  )
  const semesterCount = Number(selected.value.schoolingYears) * 2

  return Array.from({ length: semesterCount }, (_, index) => {
    const semester = index + 1
    const items = courses
      .filter((course: any) => Number(course.recommendedSemester) === semester)
      .sort((first: any, second: any) =>
        first.moduleCode.localeCompare(second.moduleCode) ||
        first.courseCode.localeCompare(second.courseCode),
      )
    return {
      semester,
      courses: items,
      credits: items.reduce((sum: number, course: any) => sum + Number(course.credits), 0),
      totalHours: items.reduce((sum: number, course: any) => sum + Number(course.totalHours), 0),
    }
  })
})

async function loadPlans(keepSelection = true) {
  loading.value = true
  try {
    const { data } = await http.get('/curriculum-plans', {
      params: {
        ...query,
        keyword: query.keyword || undefined,
      },
    })
    plans.value = data.items
    total.value = data.total
    const targetId = keepSelection && selected.value
      ? selected.value.id
      : plans.value[0]?.id
    if (targetId && plans.value.some((item) => item.id === targetId)) {
      await loadDetail(targetId)
    } else {
      selected.value = null
    }
  } catch (error) {
    ElMessage.error(apiErrorMessage(error))
  } finally {
    loading.value = false
  }
}

async function loadDetail(id: string) {
  detailLoading.value = true
  try {
    selected.value = (await http.get(`/curriculum-plans/${id}`)).data
  } catch (error) {
    ElMessage.error(apiErrorMessage(error))
  } finally {
    detailLoading.value = false
  }
}

async function loadCourseGroups() {
  try {
    courseGroups.value = (await http.get('/course-groups')).data
  } catch (error) {
    ElMessage.error(apiErrorMessage(error))
  }
}

function openCourseGroups() {
  courseGroupDialog.value = true
  openCourseGroup(activeCourseGroupId.value || undefined)
}

function openCourseGroup(id?: string) {
  activeCourseGroupId.value = id ?? ''
  const group = courseGroups.value.find((item) => item.id === id)
  Object.assign(courseGroupForm, {
    code: group?.code ?? '', name: group?.name ?? '', description: group?.description ?? '',
  })
  courseGroupCourseForm.courseId = undefined
}

async function saveCourseGroup() {
  if (!courseGroupForm.code?.trim() || !courseGroupForm.name?.trim()) {
    ElMessage.warning('请填写课程组编码和名称。')
    return
  }
  try {
    if (activeCourseGroupId.value) {
      await http.put(`/course-groups/${activeCourseGroupId.value}`, courseGroupForm)
    } else {
      const { data } = await http.post('/course-groups', courseGroupForm)
      activeCourseGroupId.value = data.id
    }
    await loadCourseGroups()
    openCourseGroup(activeCourseGroupId.value)
    ElMessage.success('课程组已保存')
  } catch (error) { ElMessage.error(apiErrorMessage(error)) }
}

async function deleteCourseGroup() {
  if (!activeCourseGroup.value) return
  try {
    await ElMessageBox.confirm(`确定删除课程组“${activeCourseGroup.value.name}”吗？`, '删除课程组', { type: 'warning' })
    await http.delete(`/course-groups/${activeCourseGroupId.value}`)
    await loadCourseGroups()
    openCourseGroup()
  } catch (error: any) {
    if (error !== 'cancel' && error !== 'close') ElMessage.error(apiErrorMessage(error))
  }
}

async function addCourseToGroup() {
  if (!activeCourseGroupId.value || !courseGroupCourseForm.courseId) return
  try {
    await http.post(`/course-groups/${activeCourseGroupId.value}/courses`, courseGroupCourseForm)
    await loadCourseGroups()
    openCourseGroup(activeCourseGroupId.value)
  } catch (error) { ElMessage.error(apiErrorMessage(error)) }
}

async function removeCourseFromGroup(courseId: string) {
  try {
    await http.delete(`/course-groups/${activeCourseGroupId.value}/courses/${courseId}`)
    await loadCourseGroups()
    openCourseGroup(activeCourseGroupId.value)
  } catch (error) { ElMessage.error(apiErrorMessage(error)) }
}

function openCourseGroupImport(moduleId: string) {
  activeModuleId.value = moduleId
  Object.assign(courseGroupImportForm, {
    courseGroupId: courseGroups.value[0]?.id, recommendedSemester: 1, type: 'Elective', notes: '',
  })
  courseGroupImportDialog.value = true
}

async function importCourseGroup() {
  if (!courseGroupImportForm.courseGroupId) {
    ElMessage.warning('请选择课程组。')
    return
  }
  if (!await confirmPublishedChange('课程组导入')) return
  try {
    await http.post(`/curriculum-plans/${selected.value.id}/modules/${activeModuleId.value}/course-groups/${courseGroupImportForm.courseGroupId}`, courseGroupImportForm)
    courseGroupImportDialog.value = false
    await loadDetail(selected.value.id)
    ElMessage.success('课程组已导入，可按本方案需要继续逐门调整。')
  } catch (error) { ElMessage.error(apiErrorMessage(error)) }
}

function resetFilters() {
  Object.assign(query, {
    page: 1,
    keyword: '',
    collegeId: isCollegeAdmin.value ? auth.user?.collegeId : undefined,
    majorId: undefined,
    effectiveGrade: undefined,
    status: undefined,
  })
  loadPlans(false)
}

function changeCollege() {
  if (query.majorId &&
      !filteredMajors.value.some((item) => item.id === query.majorId)) {
    query.majorId = undefined
  }
}

function openPlan(row?: any) {
  editingPlanId.value = row?.id ?? ''
  editingPlanStatus.value = row?.status ?? ''
  Object.keys(planForm).forEach((key) => delete planForm[key])
  Object.assign(planForm, {
    majorId: row?.majorId,
    name: row?.name ?? '',
    version: row?.version ?? `${new Date().getFullYear()}版`,
    effectiveGrade: row?.effectiveGrade ?? new Date().getFullYear(),
    totalCredits: row?.totalCredits ?? 160,
    description: row?.description ?? '',
  })
  planDialog.value = true
}

async function confirmPublishedChange(action: string) {
  if (!isPublished.value) return true
  try {
    await ElMessageBox.confirm(
      `${action}保存后会立即影响学生端培养方案展示及毕业审核依据。确定继续吗？`,
      '修改已发布方案',
      {
        type: 'warning',
        confirmButtonText: '确认修改',
        cancelButtonText: '取消',
      },
    )
    return true
  } catch {
    return false
  }
}

async function savePlan() {
  if (!planForm.majorId || !planForm.name?.trim() || !planForm.version?.trim()) {
    ElMessage.warning('请填写专业、方案名称和版本号。')
    return
  }
  if (editingPlanId.value && !await confirmPublishedChange('方案信息')) return
  try {
    if (editingPlanId.value) {
      await http.put(`/curriculum-plans/${editingPlanId.value}`, planForm)
    } else {
      await http.post('/curriculum-plans', planForm)
    }
    ElMessage.success(editingPlanId.value ? '方案信息已更新' : '培养方案草稿已创建')
    planDialog.value = false
    await loadPlans(false)
  } catch (error) {
    ElMessage.error(apiErrorMessage(error))
  }
}

function openClone() {
  Object.assign(cloneForm, {
    name: selected.value.name,
    version: `${new Date().getFullYear()}版`,
    effectiveGrade: Math.max(new Date().getFullYear(), selected.value.effectiveGrade + 1),
  })
  cloneDialog.value = true
}

async function clonePlan() {
  try {
    await http.post(`/curriculum-plans/${selected.value.id}/clone`, cloneForm)
    ElMessage.success('已复制为新的草稿版本')
    cloneDialog.value = false
    await loadPlans(false)
  } catch (error) {
    ElMessage.error(apiErrorMessage(error))
  }
}

async function publishPlan() {
  try {
    await ElMessageBox.confirm(
      '发布后该版本将成为学生端展示和毕业审核依据，并自动归档同专业、同年级的旧发布版本。已发布方案仍可调整课程内容，但适用专业、年级和版本号不可更改。确定发布吗？',
      '发布培养方案',
      { type: 'warning', confirmButtonText: '确认发布', cancelButtonText: '取消' },
    )
    await http.post(`/curriculum-plans/${selected.value.id}/publish`)
    ElMessage.success('培养方案已发布')
    await loadPlans()
  } catch (error: any) {
    if (error !== 'cancel' && error !== 'close') ElMessage.error(apiErrorMessage(error))
  }
}

async function deletePlan() {
  try {
    await ElMessageBox.confirm('确定删除这份草稿及其全部课程配置吗？', '删除草稿', {
      type: 'warning',
      confirmButtonText: '删除',
      cancelButtonText: '取消',
    })
    await http.delete(`/curriculum-plans/${selected.value.id}`)
    ElMessage.success('草稿已删除')
    await loadPlans(false)
  } catch (error: any) {
    if (error !== 'cancel' && error !== 'close') ElMessage.error(apiErrorMessage(error))
  }
}

function openModule(module?: any) {
  editingModuleId.value = module?.id ?? ''
  Object.assign(moduleForm, {
    code: module?.code ?? '',
    name: module?.name ?? '',
    requiredCredits: module?.requiredCredits ?? 0,
    sortOrder: module?.sortOrder ?? (selected.value.modules.length + 1) * 10,
  })
  moduleDialog.value = true
}

async function saveModule() {
  if (!moduleForm.code?.trim() || !moduleForm.name?.trim()) {
    ElMessage.warning('请填写模块编码和名称。')
    return
  }
  if (!await confirmPublishedChange('课程模块')) return
  try {
    const base = `/curriculum-plans/${selected.value.id}/modules`
    if (editingModuleId.value) await http.put(`${base}/${editingModuleId.value}`, moduleForm)
    else await http.post(base, moduleForm)
    moduleDialog.value = false
    await loadDetail(selected.value.id)
  } catch (error) {
    ElMessage.error(apiErrorMessage(error))
  }
}

async function deleteModule(module: any) {
  try {
    const impact = isPublished.value
      ? '删除后会立即影响学生端展示及毕业审核。'
      : ''
    await ElMessageBox.confirm(`删除“${module.name}”及其中课程？${impact}`, '删除课程模块', {
      type: 'warning',
    })
    await http.delete(`/curriculum-plans/${selected.value.id}/modules/${module.id}`)
    await loadDetail(selected.value.id)
  } catch (error: any) {
    if (error !== 'cancel' && error !== 'close') ElMessage.error(apiErrorMessage(error))
  }
}

function openCourse(moduleId: string, item?: any) {
  activeModuleId.value = moduleId
  editingCourseId.value = item?.id ?? ''
  Object.assign(courseForm, {
    courseId: item?.courseId,
    recommendedSemester: item?.recommendedSemester ?? 1,
    type: item?.type ?? 'Required',
    notes: item?.notes ?? '',
  })
  courseDialog.value = true
}

async function saveCourse() {
  if (!courseForm.courseId) {
    ElMessage.warning('请选择课程。')
    return
  }
  if (!await confirmPublishedChange('方案课程')) return
  try {
    const base = `/curriculum-plans/${selected.value.id}/modules/${activeModuleId.value}/courses`
    if (editingCourseId.value) await http.put(`${base}/${editingCourseId.value}`, courseForm)
    else await http.post(base, courseForm)
    courseDialog.value = false
    await loadDetail(selected.value.id)
  } catch (error) {
    ElMessage.error(apiErrorMessage(error))
  }
}

async function deleteCourse(moduleId: string, item: any) {
  try {
    const impact = isPublished.value
      ? '移除后会立即影响学生端展示及毕业审核。'
      : ''
    await ElMessageBox.confirm(`从方案中移除“${item.courseName}”？${impact}`, '移除课程', {
      type: 'warning',
    })
    await http.delete(
      `/curriculum-plans/${selected.value.id}/modules/${moduleId}/courses/${item.id}`,
    )
    await loadDetail(selected.value.id)
  } catch (error: any) {
    if (error !== 'cancel' && error !== 'close') ElMessage.error(apiErrorMessage(error))
  }
}

onMounted(async () => {
  const [optionRes, courseRes] = await Promise.all([
    http.get('/curriculum-plans/filter-options'),
    http.get('/courses/options'),
    loadCourseGroups(),
  ])
  colleges.value = optionRes.data.colleges
  majors.value = optionRes.data.majors
  grades.value = optionRes.data.grades
  courses.value = courseRes.data
  if (isCollegeAdmin.value && auth.user?.collegeId) {
    query.collegeId = auth.user.collegeId
  }
  await loadPlans(false)
})
</script>

<template>
  <div class="page-stack">
    <section class="page-intro">
      <div>
        <span class="section-kicker">PROGRAMME OF STUDY</span>
        <h2>培养方案</h2>
        <p>由学院按专业和入学年级维护课程结构；已发布方案可受控调整，修改结果即时生效。</p>
      </div>
      <div class="page-intro-actions">
        <el-button v-if="canManageCourseGroups" :icon="Collection" @click="openCourseGroups">课程组</el-button>
        <el-button type="primary" :icon="Plus" @click="openPlan()">新建方案</el-button>
      </div>
    </section>

    <section class="maintenance-scope" aria-label="培养方案维护范围">
      <div>
        <span>维护主体</span>
        <b>{{ isCollegeAdmin ? '学院教务' : '校级统筹' }}</b>
      </div>
      <div>
        <span>当前范围</span>
        <b>{{ maintenanceScope }}</b>
      </div>
      <p>
        {{ isCollegeAdmin
          ? '可新建、编制、发布并维护本学院各专业培养方案'
          : '可跨学院查看、发布并统筹维护培养方案版本' }}
      </p>
    </section>

    <section class="curriculum-filter">
      <el-input v-model="query.keyword" :prefix-icon="Search" clearable placeholder="搜索方案、版本或专业" @keyup.enter="query.page = 1; loadPlans(false)" />
      <el-select
        v-model="query.effectiveGrade"
        clearable
        placeholder="全部年级"
      >
        <el-option v-for="grade in availableGrades" :key="grade" :label="`${grade} 级`" :value="grade" />
      </el-select>
      <el-select
        v-model="query.collegeId"
        clearable
        :disabled="isCollegeAdmin"
        placeholder="全部学院"
        @change="changeCollege"
      >
        <el-option v-for="item in colleges" :key="item.id" :label="item.name" :value="item.id" />
      </el-select>
      <el-select v-model="query.majorId" clearable filterable placeholder="全部专业">
        <el-option v-for="item in filteredMajors" :key="item.id" :label="item.name" :value="item.id" />
      </el-select>
      <el-select v-model="query.status" clearable placeholder="全部状态">
        <el-option v-for="(label, value) in statusLabels" :key="value" :label="label" :value="value" />
      </el-select>
      <el-button type="primary" @click="query.page = 1; loadPlans(false)">查询</el-button>
      <el-button :icon="Refresh" @click="resetFilters">重置</el-button>
    </section>

    <div class="curriculum-workspace">
      <aside v-loading="loading" class="plan-list">
        <button
          v-for="plan in plans"
          :key="plan.id"
          type="button"
          :class="{ active: selected?.id === plan.id }"
          @click="loadDetail(plan.id)"
        >
          <span>{{ plan.majorName }} · {{ plan.effectiveGrade }}级</span>
          <b>{{ plan.name }}</b>
          <small>{{ plan.version }} · {{ plan.courseCount }} 门课程</small>
          <i :class="plan.status.toLowerCase()">{{ statusLabels[plan.status] }}</i>
        </button>
        <el-empty v-if="!loading && plans.length === 0" description="暂无培养方案" :image-size="70" />
        <div class="plan-pagination">
          <span>共 {{ total }} 版</span>
          <el-pagination v-model:current-page="query.page" :page-size="query.pageSize" :total="total" layout="prev, next" @current-change="loadPlans(false)" />
        </div>
      </aside>

      <main v-loading="detailLoading" class="plan-detail">
        <el-empty v-if="!selected" description="请选择或新建一份培养方案" />
        <template v-else>
          <header class="plan-detail-head">
            <div>
              <span>{{ selected.collegeName }} / {{ selected.majorName }}</span>
              <h3>{{ selected.name }}</h3>
              <p>{{ selected.version }} · 适用 {{ selected.effectiveGrade }} 级 · {{ selected.schoolingYears }} 年制</p>
            </div>
            <div class="plan-actions">
              <el-button v-if="canEdit" @click="openPlan(selected)">编辑</el-button>
              <el-button :icon="CopyDocument" @click="openClone">修订并创建草稿</el-button>
              <el-button v-if="isDraft" type="success" :icon="Promotion" @click="publishPlan">发布</el-button>
              <el-button v-if="isDraft" type="danger" plain @click="deletePlan">删除</el-button>
            </div>
          </header>

          <el-alert
            v-if="isPublished"
            class="published-edit-notice"
            type="warning"
            show-icon
            :closable="false"
            title="当前方案已发布，修改保存后会立即影响学生端展示及毕业审核依据；适用专业、入学年级和版本号不可更改。"
          />

          <div class="plan-metrics">
            <div><span>方案状态</span><b>{{ statusLabels[selected.status] }}</b></div>
            <div><span>总学分要求</span><b>{{ selected.totalCredits }}</b></div>
            <div><span>模块学分合计</span><b :class="{ warning: configuredCredits !== Number(selected.totalCredits) }">{{ configuredCredits }}</b></div>
            <div><span>课程数量</span><b>{{ selected.modules.reduce((sum: number, item: any) => sum + item.courses.length, 0) }}</b></div>
          </div>

          <div class="module-toolbar">
            <div>
              <b>{{ detailView === 'structure' ? '课程结构' : '学期视图' }}</b>
              <span>{{ detailView === 'structure'
                ? '指定必修须逐门通过；英语、体育等多选课程用“组内选修”，修满模块最低学分即可'
                : '按建议修读学期展示课程安排，包含每学期的课程数量、学分和学时。' }}</span>
            </div>
            <div class="curriculum-view-actions">
              <el-radio-group v-model="detailView" size="small" aria-label="培养方案展示方式">
                <el-radio-button value="structure">课程结构</el-radio-button>
                <el-radio-button value="semester">学期视图</el-radio-button>
              </el-radio-group>
              <el-button v-if="canEdit && detailView === 'structure'" :icon="Plus" @click="openModule()">新增模块</el-button>
            </div>
          </div>

          <template v-if="detailView === 'structure'">
          <section v-for="module in selected.modules" :key="module.id" class="curriculum-module">
            <header>
              <div>
                <span>{{ module.code }}</span>
                <h4>{{ module.name }}</h4>
              </div>
              <p>
                最低 {{ module.requiredCredits }} 学分 · 已配置 {{ module.assignedCredits }} 学分
                <template v-if="module.courses.some((course: any) => course.type === 'Elective')">
                  · 课程组选项
                </template>
              </p>
              <div v-if="canEdit">
                <el-button link type="primary" @click="openModule(module)">编辑</el-button>
                <el-button link type="danger" @click="deleteModule(module)">删除</el-button>
                <el-button size="small" @click="openCourseGroupImport(module.id)">从课程组添加</el-button>
                <el-button size="small" :icon="Plus" @click="openCourse(module.id)">添加课程</el-button>
              </div>
            </header>
            <el-table :data="module.courses" class="curriculum-course-table">
              <el-table-column prop="courseCode" label="课程编码" width="115" />
              <el-table-column label="课程名称" min-width="180">
                <template #default="{ row }"><b>{{ row.courseName }}</b></template>
              </el-table-column>
              <el-table-column label="类别" width="80">
                <template #default="{ row }">{{ courseTypeLabels[row.type] }}</template>
              </el-table-column>
              <el-table-column label="课程分类" width="100">
                <template #default="{ row }">{{ row.categoryName || '未分类' }}</template>
              </el-table-column>
              <el-table-column prop="credits" label="学分" width="70" />
              <el-table-column prop="totalHours" label="学时" width="70" />
              <el-table-column label="建议学期" width="90">
                <template #default="{ row }">第 {{ row.recommendedSemester }} 学期</template>
              </el-table-column>
              <el-table-column v-if="canEdit" label="操作" width="120">
                <template #default="{ row }">
                  <el-button link type="primary" @click="openCourse(module.id, row)">编辑</el-button>
                  <el-button link type="danger" @click="deleteCourse(module.id, row)">移除</el-button>
                </template>
              </el-table-column>
              <template #empty><el-empty description="该模块尚未配置课程" :image-size="54" /></template>
            </el-table>
          </section>
          <el-empty v-if="selected.modules.length === 0" description="先建立课程模块，再添加课程" />
          </template>

          <section v-else class="semester-view" aria-label="课程学期安排">
            <article v-for="group in semesterGroups" :key="group.semester" class="semester-card">
              <header>
                <div>
                  <span>SEMESTER {{ String(group.semester).padStart(2, '0') }}</span>
                  <h4>第 {{ group.semester }} 学期</h4>
                </div>
                <b>{{ group.courses.length }} 门</b>
              </header>
              <div class="semester-summary">
                <span>{{ group.credits }} 学分</span>
                <span>{{ group.totalHours }} 学时</span>
              </div>
              <ul v-if="group.courses.length" class="semester-courses">
                <li v-for="course in group.courses" :key="course.id">
                  <div>
                    <span>{{ course.moduleName }}</span>
                    <b>{{ course.courseName }}</b>
                    <small>{{ course.courseCode }} · {{ courseTypeLabels[course.type] }}</small>
                  </div>
                  <strong>{{ course.credits }}<small>学分</small></strong>
                </li>
              </ul>
              <p v-else class="semester-empty">本学期暂未安排课程</p>
            </article>
          </section>
        </template>
      </main>
    </div>

    <el-dialog v-model="planDialog" :title="editingPlanId ? '编辑培养方案' : '新建培养方案'" width="620px">
      <el-alert
        v-if="isEditingPublished"
        type="warning"
        show-icon
        :closable="false"
        title="已发布方案的修改会立即生效。适用专业、入学年级和版本号已锁定，如需调整请复制为新版本。"
      />
      <el-form label-position="top">
        <el-form-item label="适用专业" required>
          <el-select v-model="planForm.majorId" filterable :disabled="isEditingPublished"><el-option v-for="item in availableMajors" :key="item.id" :label="item.name" :value="item.id" /></el-select>
        </el-form-item>
        <el-form-item label="方案名称" required><el-input v-model="planForm.name" /></el-form-item>
        <div class="form-grid">
          <el-form-item label="版本号" required><el-input v-model="planForm.version" :disabled="isEditingPublished" /></el-form-item>
          <el-form-item label="适用入学年级" required><el-input-number v-model="planForm.effectiveGrade" :min="2000" :max="2200" :disabled="isEditingPublished" /></el-form-item>
        </div>
        <el-form-item label="毕业总学分要求" required><el-input-number v-model="planForm.totalCredits" :min="0.1" :precision="1" :step="0.5" /></el-form-item>
        <el-form-item label="方案说明"><el-input v-model="planForm.description" type="textarea" :rows="3" /></el-form-item>
      </el-form>
      <template #footer><el-button @click="planDialog = false">取消</el-button><el-button type="primary" @click="savePlan">保存</el-button></template>
    </el-dialog>

    <el-dialog v-model="cloneDialog" title="修订培养方案并创建草稿" width="520px">
      <p class="form-help">将完整复制当前方案为独立草稿；修订后的课程、模块和课程组导入内容均可单独调整，不影响原版本。</p>
      <el-form label-position="top">
        <el-form-item label="方案名称" required><el-input v-model="cloneForm.name" /></el-form-item>
        <div class="form-grid">
          <el-form-item label="新版本号" required><el-input v-model="cloneForm.version" /></el-form-item>
          <el-form-item label="适用入学年级" required><el-input-number v-model="cloneForm.effectiveGrade" :min="2000" :max="2200" /></el-form-item>
        </div>
      </el-form>
      <template #footer><el-button @click="cloneDialog = false">取消</el-button><el-button type="primary" @click="clonePlan">创建修订草稿</el-button></template>
    </el-dialog>

    <el-dialog v-model="moduleDialog" :title="editingModuleId ? '编辑课程模块' : '新增课程模块'" width="520px">
      <el-form label-position="top">
        <div class="form-grid">
          <el-form-item label="模块编码" required><el-input v-model="moduleForm.code" /></el-form-item>
          <el-form-item label="排序"><el-input-number v-model="moduleForm.sortOrder" :min="0" /></el-form-item>
        </div>
        <el-form-item label="模块名称" required><el-input v-model="moduleForm.name" /></el-form-item>
        <el-form-item label="最低学分要求">
          <el-input-number v-model="moduleForm.requiredCredits" :min="0" :precision="1" :step="0.5" />
          <span class="form-help">体育、英语等课程组填写学生必须从组内修满的学分。</span>
        </el-form-item>
      </el-form>
      <template #footer><el-button @click="moduleDialog = false">取消</el-button><el-button type="primary" @click="saveModule">保存</el-button></template>
    </el-dialog>

    <el-dialog v-model="courseDialog" :title="editingCourseId ? '编辑方案课程' : '添加方案课程'" width="560px">
      <el-form label-position="top">
        <el-form-item label="课程" required>
          <el-select v-model="courseForm.courseId" filterable>
            <el-option v-for="item in courses" :key="item.id" :label="`${item.code} · ${item.name}${item.categoryName ? ` · ${item.categoryName}` : ''}`" :value="item.id" />
          </el-select>
        </el-form-item>
        <div class="form-grid">
          <el-form-item label="修读规则"><el-select v-model="courseForm.type"><el-option v-for="(label, value) in courseTypeLabels" :key="value" :label="label" :value="value" /></el-select></el-form-item>
          <el-form-item label="建议学期"><el-input-number v-model="courseForm.recommendedSemester" :min="1" :max="selected?.schoolingYears * 2" /></el-form-item>
        </div>
        <el-form-item label="备注"><el-input v-model="courseForm.notes" type="textarea" :rows="2" /></el-form-item>
        <div class="course-rule-help">
          <b>指定必修</b><span>该门课程必须通过</span>
          <b>组内选修</b><span>足球、篮球、英语分层等作为选项，按模块最低学分验收</span>
        </div>
      </el-form>
      <template #footer><el-button @click="courseDialog = false">取消</el-button><el-button type="primary" @click="saveCourse">保存</el-button></template>
    </el-dialog>

    <el-dialog v-model="courseGroupImportDialog" title="从课程组添加课程" width="560px">
      <el-alert type="info" :closable="false" show-icon title="导入后课程会复制到当前方案，可逐门修改建议学期、修读规则和备注，不影响公共课程组。" />
      <el-form label-position="top">
        <el-form-item label="课程组" required>
          <el-select v-model="courseGroupImportForm.courseGroupId" filterable>
            <el-option v-for="group in courseGroups" :key="group.id" :label="`${group.code} · ${group.name}（${group.courseCount} 门）`" :value="group.id" />
          </el-select>
        </el-form-item>
        <p v-if="importingCourseGroup" class="form-help">将导入：{{ importingCourseGroup.courses.map((course: any) => course.courseName).join('、') }}</p>
        <div class="form-grid">
          <el-form-item label="修读规则"><el-select v-model="courseGroupImportForm.type"><el-option v-for="(label, value) in courseTypeLabels" :key="value" :label="label" :value="value" /></el-select></el-form-item>
          <el-form-item label="建议学期"><el-input-number v-model="courseGroupImportForm.recommendedSemester" :min="1" :max="selected?.schoolingYears * 2" /></el-form-item>
        </div>
        <el-form-item label="统一备注"><el-input v-model="courseGroupImportForm.notes" type="textarea" :rows="2" /></el-form-item>
      </el-form>
      <template #footer><el-button @click="courseGroupImportDialog = false">取消</el-button><el-button type="primary" @click="importCourseGroup">导入课程组</el-button></template>
    </el-dialog>

    <el-dialog v-model="courseGroupDialog" title="公共课程组" width="920px">
      <div class="course-group-manager">
        <aside>
          <el-button type="primary" :icon="Plus" @click="openCourseGroup()">新建课程组</el-button>
          <button v-for="group in courseGroups" :key="group.id" type="button" :class="{ active: activeCourseGroupId === group.id }" @click="openCourseGroup(group.id)">
            <span>{{ group.code }}</span><b>{{ group.name }}</b><small>{{ group.courseCount }} 门课程</small>
          </button>
        </aside>
        <main>
          <el-form label-position="top">
            <div class="form-grid">
              <el-form-item label="课程组编码" required><el-input v-model="courseGroupForm.code" /></el-form-item>
              <el-form-item label="课程组名称" required><el-input v-model="courseGroupForm.name" /></el-form-item>
            </div>
            <el-form-item label="说明"><el-input v-model="courseGroupForm.description" type="textarea" :rows="2" /></el-form-item>
          </el-form>
          <div class="course-group-actions"><el-button type="primary" @click="saveCourseGroup">保存课程组</el-button><el-button v-if="activeCourseGroup" type="danger" plain @click="deleteCourseGroup">删除</el-button></div>
          <div v-if="activeCourseGroup" class="course-group-add">
            <b>组内课程</b>
            <el-select v-model="courseGroupCourseForm.courseId" filterable placeholder="选择课程加入课程组"><el-option v-for="course in courses" :key="course.id" :label="`${course.code} · ${course.name}`" :value="course.id" /></el-select>
            <el-button type="primary" @click="addCourseToGroup">加入</el-button>
          </div>
          <el-table v-if="activeCourseGroup" :data="activeCourseGroup.courses">
            <el-table-column prop="courseCode" label="课程编码" width="120" />
            <el-table-column prop="courseName" label="课程名称" />
            <el-table-column prop="credits" label="学分" width="80" />
            <el-table-column label="操作" width="80"><template #default="{ row }"><el-button link type="danger" @click="removeCourseFromGroup(row.courseId)">移除</el-button></template></el-table-column>
          </el-table>
        </main>
      </div>
    </el-dialog>
  </div>
</template>
