<script setup lang="ts">
import { computed, onMounted, reactive, ref, watch } from 'vue'
import { Document, Download, Plus, Refresh, Search, Upload } from '@element-plus/icons-vue'
import { useRoute } from 'vue-router'
import http, { apiErrorMessage } from '../api/http'
import { downloadApiFile, importExcel } from '../api/excel'
import { useAuthStore } from '../stores/auth'
import { academicTermRowClass } from '../utils/academicTerms'

type Kind = 'campuses' | 'colleges' | 'majors' | 'classes' | 'terms' | 'buildings' | 'classrooms' | 'course-categories'
interface Row {
  id: string
  code: string
  name: string
  isEnabled: boolean
  academicYear?: string
  isCurrent?: boolean
  isArchived?: boolean
  [key: string]: unknown
}

const allTabs: { key: Kind; label: string; hint: string }[] = [
  { key: 'campuses', label: '校区', hint: '学校的物理校区' },
  { key: 'colleges', label: '学院', hint: '教学组织单位' },
  { key: 'majors', label: '专业', hint: '专业与授予学位' },
  { key: 'classes', label: '行政班', hint: '按年级组织的班级' },
  { key: 'terms', label: '学期', hint: '教学运行时间轴' },
  { key: 'buildings', label: '教学楼', hint: '校区内教学建筑' },
  { key: 'classrooms', label: '教室', hint: '可排课教学空间' },
  { key: 'course-categories', label: '课程分类', hint: '课程所属教学领域' },
]

const auth = useAuthStore()
const route = useRoute()
const groups = {
  organization: {
    title: '组织机构',
    kicker: 'ORGANIZATION DIRECTORY',
    description: '维护校区、学院、专业与行政班的稳定组织层级。',
    kinds: ['campuses', 'colleges', 'majors', 'classes'] as Kind[],
  },
  terms: {
    title: '学年学期',
    kicker: 'ACADEMIC CALENDAR',
    description: '集中维护教学年度、学期边界与当前运行学期。',
    kinds: ['terms'] as Kind[],
  },
  facilities: {
    title: '教学场所',
    kicker: 'TEACHING FACILITIES',
    description: '按校区和教学楼维护可用于排课的教室资源。',
    kinds: ['buildings', 'classrooms'] as Kind[],
  },
  'course-categories': {
    title: '课程分类',
    kicker: 'COURSE TAXONOMY',
    description: '统一维护基础课、美育、德育、创新创业等课程教学领域。课程性质与课程分类相互独立。',
    kinds: ['course-categories'] as Kind[],
  },
}
const group = computed(() => {
  const key = String(route.meta.baseGroup ?? 'organization') as keyof typeof groups
  return groups[key] ?? groups.organization
})
const tabs = computed(() =>
  allTabs.filter((tab) => group.value.kinds.includes(tab.key)),
)
const active = ref<Kind>(group.value.kinds[0])
const rows = ref<Row[]>([])
const loading = ref(false)
const importing = ref(false)
const fileInput = ref<HTMLInputElement>()
const dialogVisible = ref(false)
const editingId = ref('')
const keyword = ref('')
const references = reactive<Record<string, any[]>>({
  campuses: [], colleges: [], majors: [], buildings: [], counselors: [],
})
const form = reactive<Record<string, any>>({})
const listFilters = reactive({
  collegeId: undefined as string | undefined,
  majorId: undefined as string | undefined,
  grade: undefined as number | undefined,
  campusId: undefined as string | undefined,
  buildingId: undefined as string | undefined,
  minimumCapacity: undefined as number | undefined,
  teachingVenueNature: undefined as number | undefined,
  isEnabled: undefined as boolean | undefined,
})

const title = computed(() => tabs.value.find((x) => x.key === active.value)?.label ?? '')
const canManage = computed(() =>
  auth.user?.roles.some((role) => ['SuperAdmin', 'AcademicAdmin'].includes(role)) ?? false,
)
const filteredRows = computed(() => {
  const q = keyword.value.trim().toLowerCase()
  if (!q) return rows.value
  return rows.value.filter((row) =>
    [row.code, row.name, row.collegeName, row.campusName, row.majorName, row.buildingName]
      .filter(Boolean).some((value) => String(value).toLowerCase().includes(q)),
  )
})
const filteredMajors = computed(() => references.majors.filter((item: any) =>
  !listFilters.collegeId || item.collegeId === listFilters.collegeId))
const filteredBuildings = computed(() => references.buildings.filter((item: any) =>
  !listFilters.campusId || item.campusId === listFilters.campusId))
const currentPage = ref(1)
const pageSize = ref(20)
const total = ref(0)
const serverPaged = computed(() =>
  active.value === 'classes' || active.value === 'classrooms')
let keywordTimer: ReturnType<typeof setTimeout> | undefined
const pagedRows = computed(() => serverPaged.value
  ? filteredRows.value
  : filteredRows.value.slice(
      (currentPage.value - 1) * pageSize.value,
      currentPage.value * pageSize.value,
    ))
const venueNatureOptions = [
  { value: 1, label: '普通教室' },
  { value: 2, label: '实验室' },
  { value: 4, label: '实训室' },
  { value: 8, label: '计算机机房' },
  { value: 16, label: '语音室' },
  { value: 32, label: '体育场地' },
  { value: 64, label: '艺术场地' },
]
const venueNatureValue = (value: unknown) => {
  if (typeof value === 'number') return value
  if (typeof value !== 'string') return 0
  const names: Record<string, number> = {
    GeneralClassroom: 1, Laboratory: 2, TrainingRoom: 4, ComputerLab: 8,
    LanguageLab: 16, SportsVenue: 32, ArtsVenue: 64,
  }
  return value.split(',').reduce((sum, name) => sum | (names[name.trim()] ?? 0), 0)
}
const venueNatureLabel = (value: unknown) => venueNatureOptions
  .filter((item) => (venueNatureValue(value) & item.value) !== 0)
  .map((item) => item.label)
  .join('、') || '未设置'

function resetForm(row?: Row) {
  Object.keys(form).forEach((key) => delete form[key])
  Object.assign(form, {
    code: '', name: '', sortOrder: 0, isEnabled: true,
    campusId: undefined, collegeId: undefined, majorId: undefined, buildingId: undefined,
    shortName: '', degreeType: '学士', schoolingYears: 4,
    grade: new Date().getFullYear(), counselorUserId: undefined,
    academicYear: `${new Date().getFullYear()}-${new Date().getFullYear() + 1}`,
    season: 'Autumn', startDate: '', endDate: '', isCurrent: false,
    capacity: 60, roomType: '普通教室', teachingVenueNatures: [1], equipment: '',
  }, row ?? {})
  if (active.value === 'classrooms') {
    const value = venueNatureValue((row as any)?.teachingVenueNature ?? 1)
    form.teachingVenueNatures = venueNatureOptions
      .filter((item) => (value & item.value) !== 0)
      .map((item) => item.value)
  }
}

async function load(resetPage = true) {
  loading.value = true
  if (resetPage) currentPage.value = 1
  try {
    const response = await http.get(`/base-data/${active.value}`, {
      params: serverPaged.value
        ? {
            page: currentPage.value,
            pageSize: pageSize.value,
            keyword: keyword.value.trim() || undefined,
            ...(active.value === 'classes' ? {
              collegeId: listFilters.collegeId,
              majorId: listFilters.majorId,
              grade: listFilters.grade,
              isEnabled: listFilters.isEnabled,
            } : {
              campusId: listFilters.campusId,
              buildingId: listFilters.buildingId,
              minimumCapacity: listFilters.minimumCapacity,
              teachingVenueNature: listFilters.teachingVenueNature,
              isEnabled: listFilters.isEnabled,
            }),
          }
        : undefined,
    })
    if (serverPaged.value) {
      rows.value = response.data.items
      total.value = response.data.total
      if (rows.value.length === 0 && currentPage.value > 1) {
        currentPage.value--
        await load(false)
      }
    } else {
      rows.value = response.data
      total.value = rows.value.length
    }
  } catch (error) {
    ElMessage.error(apiErrorMessage(error))
  } finally {
    loading.value = false
  }
}

async function loadReferences() {
  const kinds = ['campuses', 'colleges', 'majors', 'buildings'] as const
  await Promise.all(kinds.map(async (kind) => {
    references[kind] = (await http.get(`/base-data/${kind}`)).data
  }))
  if (canManage.value) {
    references.counselors = (await http.get('/base-data/counselors')).data
  }
}

async function changeTab() {
  keyword.value = ''
  Object.assign(listFilters, {
    collegeId: undefined, majorId: undefined, grade: undefined,
    campusId: undefined, buildingId: undefined, minimumCapacity: undefined,
    teachingVenueNature: undefined, isEnabled: undefined,
  })
  await load()
}

async function downloadTemplate() {
  try {
    await downloadApiFile(
      `/base-data/${active.value}/template`,
      `${title.value}导入模板.xlsx`,
    )
  } catch (error) {
    ElMessage.error(apiErrorMessage(error))
  }
}

async function exportRows() {
  try {
    await downloadApiFile(
      `/base-data/${active.value}/export`,
      `${title.value}.xlsx`,
    )
    ElMessage.success(`${title.value}已导出`)
  } catch (error) {
    ElMessage.error(apiErrorMessage(error))
  }
}

function chooseImportFile() {
  fileInput.value?.click()
}

async function handleImport(event: Event) {
  const input = event.target as HTMLInputElement
  const file = input.files?.[0]
  input.value = ''
  if (!file) return
  importing.value = true
  try {
    const { data } = await importExcel(`/base-data/${active.value}/import`, file)
    ElMessage.success(`导入完成：新增 ${data.created} 条，更新 ${data.updated} 条`)
    await Promise.all([load(), loadReferences()])
  } catch (error) {
    ElMessage.error(apiErrorMessage(error))
  } finally {
    importing.value = false
  }
}

function openCreate() {
  editingId.value = ''
  resetForm()
  dialogVisible.value = true
}

function openEdit(row: any) {
  editingId.value = row.id
  resetForm(row)
  dialogVisible.value = true
}

async function save() {
  if (!form.code?.trim() || !form.name?.trim()) {
    ElMessage.warning('请填写编码和名称。')
    return
  }
  try {
    const payload = active.value === 'classrooms'
      ? {
          ...form,
          teachingVenueNature: form.teachingVenueNatures.reduce((value: number, item: number) => value | item, 0),
        }
      : form
    if (editingId.value) {
      await http.put(`/base-data/${active.value}/${editingId.value}`, payload)
    } else {
      await http.post(`/base-data/${active.value}`, payload)
    }
    ElMessage.success(editingId.value ? '已保存修改' : `已新增${title.value}`)
    dialogVisible.value = false
    await Promise.all([load(), loadReferences()])
  } catch (error) {
    ElMessage.error(apiErrorMessage(error))
  }
}

async function remove(row: any) {
  try {
    await ElMessageBox.confirm(
      `确定删除“${row.name}”吗？已被业务引用的数据将无法删除。`,
      '删除确认',
      { type: 'warning', confirmButtonText: '删除', cancelButtonText: '取消' },
    )
    await http.delete(`/base-data/${active.value}/${row.id}`)
    ElMessage.success('已删除')
    await load()
  } catch (error: any) {
    if (error !== 'cancel' && error !== 'close') ElMessage.error(apiErrorMessage(error))
  }
}

function termTableRowClass({ row }: { row: any }) {
  return active.value === 'terms' ? academicTermRowClass(row) : ''
}

async function setCurrentTerm(row: any) {
  try {
    await ElMessageBox.confirm(
      `将“${row.name}”切换为当前学期？其他学期会自动转为历史显示，但不会自动归档，也不会冻结成绩和补考。`,
      '切换当前学期',
      { type: 'warning', confirmButtonText: '切换为当前', cancelButtonText: '取消' },
    )
    await http.post(`/base-data/terms/${row.id}/set-current`)
    ElMessage.success(`当前学期已切换为“${row.name}”`)
    await load()
  } catch (error: any) {
    if (error !== 'cancel' && error !== 'close') ElMessage.error(apiErrorMessage(error))
  }
}

async function toggleTermArchive(row: any) {
  const restoring = row.isArchived
  try {
    await ElMessageBox.confirm(
      restoring
        ? `撤销“${row.name}”的归档状态？撤销后仍作为历史学期显示，可再次设为当前。`
        : `归档“${row.name}”？归档只降低历史数据的显示优先级，不会冻结成绩更正或补考成绩录入。`,
      restoring ? '撤销学期归档' : '归档学期',
      {
        type: restoring ? 'info' : 'warning',
        confirmButtonText: restoring ? '撤销归档' : '确认归档',
        cancelButtonText: '取消',
      },
    )
    await http.post(`/base-data/terms/${row.id}/${restoring ? 'unarchive' : 'archive'}`)
    ElMessage.success(restoring ? '已撤销归档' : '学期已归档')
    await load()
  } catch (error: any) {
    if (error !== 'cancel' && error !== 'close') ElMessage.error(apiErrorMessage(error))
  }
}

onMounted(async () => {
  await Promise.all([load(), loadReferences()])
})

watch(
  () => keyword.value,
  () => {
    currentPage.value = 1
    if (keywordTimer) clearTimeout(keywordTimer)
    if (serverPaged.value) {
      keywordTimer = setTimeout(() => { void load(false) }, 250)
    }
  },
)

watch(
  () => route.meta.baseGroup,
  async () => {
    active.value = group.value.kinds[0]
    keyword.value = ''
    await load()
  },
)
</script>

<template>
  <div class="page-stack">
    <section class="page-intro">
      <div>
        <span class="section-kicker">{{ group.kicker }}</span>
        <h2>{{ group.title }}</h2>
        <p>{{ group.description }}</p>
      </div>
      <div class="page-actions">
        <el-button v-if="canManage" type="primary" :icon="Plus" @click="openCreate">
          新增{{ title }}
        </el-button>
      </div>
    </section>

    <section class="data-card">
      <nav
        v-if="tabs.length > 1"
        class="data-tabs"
        :style="{ '--tab-count': tabs.length }"
        aria-label="基础数据分类"
      >
        <button
          v-for="tab in tabs"
          :key="tab.key"
          type="button"
          :class="{ active: active === tab.key }"
          @click="active = tab.key; changeTab()"
        >
          <b>{{ tab.label }}</b>
          <span>{{ tab.hint }}</span>
        </button>
      </nav>

      <div class="table-toolbar">
        <el-input v-model="keyword" :prefix-icon="Search" clearable placeholder="搜索编码、名称或所属单位" />
        <template v-if="active === 'classes'">
          <el-select v-model="listFilters.collegeId" clearable placeholder="全部学院" @change="() => { listFilters.majorId = undefined; load() }">
            <el-option v-for="item in references.colleges" :key="item.id" :label="item.name" :value="item.id" />
          </el-select>
          <el-select v-model="listFilters.majorId" clearable filterable placeholder="全部专业" @change="load()">
            <el-option v-for="item in filteredMajors" :key="item.id" :label="item.name" :value="item.id" />
          </el-select>
          <el-input-number v-model="listFilters.grade" :min="1900" :max="2200" controls-position="right" placeholder="入学年级" @change="load()" />
        </template>
        <template v-else-if="active === 'classrooms'">
          <el-select v-model="listFilters.campusId" clearable placeholder="全部校区" @change="() => { listFilters.buildingId = undefined; load() }">
            <el-option v-for="item in references.campuses" :key="item.id" :label="item.name" :value="item.id" />
          </el-select>
          <el-select v-model="listFilters.buildingId" clearable filterable placeholder="全部教学楼" @change="load()">
            <el-option v-for="item in filteredBuildings" :key="item.id" :label="item.name" :value="item.id" />
          </el-select>
          <el-select v-model="listFilters.teachingVenueNature" clearable placeholder="场地性质" @change="load()">
            <el-option v-for="item in venueNatureOptions" :key="item.value" :label="item.label" :value="item.value" />
          </el-select>
          <el-input-number v-model="listFilters.minimumCapacity" :min="1" controls-position="right" placeholder="最小容量" @change="load()" />
        </template>
        <el-select v-if="serverPaged" v-model="listFilters.isEnabled" clearable placeholder="全部状态" @change="load()">
          <el-option label="启用" :value="true" />
          <el-option label="停用" :value="false" />
        </el-select>
        <el-button :icon="Search" @click="load()">查询</el-button>
        <el-button :icon="Refresh" @click="() => load(false)">刷新</el-button>
        <template v-if="canManage">
          <el-button :icon="Document" @click="downloadTemplate">下载模板</el-button>
          <el-button :icon="Upload" :loading="importing" @click="chooseImportFile">Excel 导入</el-button>
          <el-button :icon="Download" @click="exportRows">导出结果</el-button>
          <input
            ref="fileInput"
            class="visually-hidden"
            type="file"
            accept=".xlsx"
            @change="handleImport"
          />
        </template>
        <span>共 {{ serverPaged ? total : filteredRows.length }} 条</span>
      </div>

      <el-alert
        v-if="active === 'terms'"
        class="term-policy-note"
        type="info"
        :closable="false"
        show-icon
        title="切换当前学期只改变默认工作学期；归档需手动执行，归档后仍可处理补考与成绩更正。"
      />

      <div v-if="active === 'terms'" class="term-mobile-list">
        <article
          v-for="row in pagedRows"
          :key="row.id"
          :class="academicTermRowClass(row)"
        >
          <header>
            <div>
              <span>{{ row.code }}</span>
              <h3>{{ row.name }}</h3>
              <p>{{ row.academicYear }}</p>
            </div>
            <el-tag v-if="row.isCurrent" type="success">当前</el-tag>
            <el-tag v-else-if="row.isArchived" type="info">已归档</el-tag>
            <span v-else class="term-history-label">历史学期</span>
          </header>
          <footer v-if="canManage">
            <el-button
              v-if="!row.isCurrent && !row.isArchived"
              size="small"
              type="success"
              plain
              @click="setCurrentTerm(row)"
            >设为当前</el-button>
            <el-button
              v-if="!row.isCurrent"
              size="small"
              :type="row.isArchived ? 'primary' : 'warning'"
              plain
              @click="toggleTermArchive(row)"
            >{{ row.isArchived ? '撤销归档' : '归档' }}</el-button>
            <el-button size="small" @click="openEdit(row)">编辑</el-button>
            <el-button
              v-if="!row.isCurrent"
              size="small"
              type="danger"
              plain
              @click="remove(row)"
            >删除</el-button>
          </footer>
        </article>
      </div>

      <el-table
        v-loading="loading"
        :data="pagedRows"
        :row-class-name="termTableRowClass"
        class="data-table"
        :class="{ 'term-desktop-table': active === 'terms' }"
      >
        <el-table-column prop="code" label="编码" min-width="130" />
        <el-table-column prop="name" label="名称" min-width="180" />
        <el-table-column v-if="active === 'colleges'" prop="campusName" label="所属校区" min-width="140" />
        <el-table-column v-if="active === 'majors'" prop="collegeName" label="所属学院" min-width="150" />
        <el-table-column v-if="active === 'majors'" prop="degreeType" label="学位类型" min-width="120" />
        <el-table-column v-if="active === 'classes'" prop="majorName" label="所属专业" min-width="170" />
        <el-table-column v-if="active === 'classes'" prop="grade" label="年级" width="90" />
        <el-table-column v-if="active === 'classes'" prop="counselorName" label="辅导员" min-width="120">
          <template #default="{ row }">{{ row.counselorName || '未分配' }}</template>
        </el-table-column>
        <el-table-column v-if="active === 'terms'" prop="academicYear" label="学年" width="120" />
        <el-table-column v-if="active === 'terms'" label="运行状态" width="120">
          <template #default="{ row }">
            <el-tag v-if="row.isCurrent" type="success">当前</el-tag>
            <el-tag v-else-if="row.isArchived" type="info">已归档</el-tag>
            <span v-else>历史学期</span>
          </template>
        </el-table-column>
        <el-table-column v-if="active === 'buildings'" prop="campusName" label="所属校区" min-width="140" />
        <el-table-column v-if="active === 'classrooms'" prop="buildingName" label="教学楼" min-width="130" />
        <el-table-column v-if="active === 'classrooms'" prop="capacity" label="容量" width="90" />
        <el-table-column v-if="active === 'classrooms'" label="场地性质" min-width="180">
          <template #default="{ row }">{{ venueNatureLabel(row.teachingVenueNature) }}</template>
        </el-table-column>
        <el-table-column label="状态" width="90">
          <template #default="{ row }">
            <span class="table-status" :class="{ off: !row.isEnabled }">{{ row.isEnabled ? '启用' : '停用' }}</span>
          </template>
        </el-table-column>
        <el-table-column
          v-if="canManage"
          label="操作"
          :width="active === 'terms' ? 280 : 150"
          fixed="right"
        >
          <template #default="{ row }">
            <template v-if="active === 'terms'">
              <el-button
                v-if="!row.isCurrent && !row.isArchived"
                link
                type="success"
                @click="setCurrentTerm(row)"
              >设为当前</el-button>
              <el-button
                v-if="!row.isCurrent"
                link
                :type="row.isArchived ? 'primary' : 'warning'"
                @click="toggleTermArchive(row)"
              >{{ row.isArchived ? '撤销归档' : '归档' }}</el-button>
            </template>
            <el-button link type="primary" @click="openEdit(row)">编辑</el-button>
            <el-button
              v-if="active !== 'terms' || !row.isCurrent"
              link
              type="danger"
              @click="remove(row)"
            >删除</el-button>
          </template>
        </el-table-column>
        <template #empty><el-empty description="暂无数据，点击右上角开始新增" /></template>
      </el-table>
      <el-pagination
        v-if="(serverPaged ? total : filteredRows.length) > pageSize"
        v-model:current-page="currentPage"
        v-model:page-size="pageSize"
        class="table-pagination"
        layout="total, sizes, prev, pager, next"
        :page-sizes="[20, 50, 100]"
        :total="serverPaged ? total : filteredRows.length"
        @current-change="() => { if (serverPaged) void load(false) }"
        @size-change="() => { if (serverPaged) void load(true) }"
      />
    </section>

    <el-dialog v-model="dialogVisible" :title="`${editingId ? '编辑' : '新增'}${title}`" width="560px">
      <el-form label-position="top" class="entity-form">
        <div class="form-grid">
          <el-form-item label="编码" required><el-input v-model="form.code" placeholder="用于唯一识别" /></el-form-item>
          <el-form-item label="名称" required><el-input v-model="form.name" /></el-form-item>
        </div>
        <el-form-item v-if="active === 'campuses'" label="地址">
          <el-input v-model="form.description" />
        </el-form-item>
        <el-form-item v-if="active === 'colleges' || active === 'buildings'" label="所属校区">
          <el-select v-model="form.campusId" clearable>
            <el-option v-for="item in references.campuses" :key="item.id" :label="item.name" :value="item.id" />
          </el-select>
        </el-form-item>
        <el-form-item v-if="active === 'colleges'" label="学院简称"><el-input v-model="form.shortName" /></el-form-item>
        <el-form-item v-if="active === 'majors'" label="所属学院" required>
          <el-select v-model="form.collegeId">
            <el-option v-for="item in references.colleges" :key="item.id" :label="item.name" :value="item.id" />
          </el-select>
        </el-form-item>
        <div v-if="active === 'majors'" class="form-grid">
          <el-form-item label="学位类型"><el-input v-model="form.degreeType" /></el-form-item>
          <el-form-item label="学制"><el-input-number v-model="form.schoolingYears" :min="1" :max="8" /></el-form-item>
        </div>
        <el-form-item v-if="active === 'classes'" label="所属专业" required>
          <el-select v-model="form.majorId" filterable>
            <el-option v-for="item in references.majors" :key="item.id" :label="item.name" :value="item.id" />
          </el-select>
        </el-form-item>
        <div v-if="active === 'classes'" class="form-grid">
          <el-form-item label="年级"><el-input-number v-model="form.grade" :min="2000" :max="2200" /></el-form-item>
          <el-form-item label="辅导员账号">
            <el-select v-model="form.counselorUserId" clearable filterable>
              <el-option
                v-for="item in references.counselors"
                :key="item.id"
                :label="`${item.displayName}${item.staffNumber ? ` · ${item.staffNumber}` : ''}`"
                :value="item.id"
              />
            </el-select>
          </el-form-item>
        </div>
        <template v-if="active === 'terms'">
          <div class="form-grid">
            <el-form-item label="学年"><el-input v-model="form.academicYear" /></el-form-item>
            <el-form-item label="学期季">
              <el-select v-model="form.season">
                <el-option label="秋季学期" value="Autumn" />
                <el-option label="春季学期" value="Spring" />
                <el-option label="夏季学期" value="Summer" />
              </el-select>
            </el-form-item>
          </div>
          <div class="form-grid">
            <el-form-item label="开始日期"><el-date-picker v-model="form.startDate" value-format="YYYY-MM-DD" /></el-form-item>
            <el-form-item label="结束日期"><el-date-picker v-model="form.endDate" value-format="YYYY-MM-DD" /></el-form-item>
          </div>
          <el-form-item>
            <el-checkbox v-model="form.isCurrent" :disabled="form.isArchived">
              设为当前学期
            </el-checkbox>
            <span v-if="form.isArchived" class="field-help">已归档学期需先撤销归档。</span>
          </el-form-item>
        </template>
        <el-form-item v-if="active === 'classrooms'" label="所属教学楼" required>
          <el-select v-model="form.buildingId">
            <el-option v-for="item in references.buildings" :key="item.id" :label="`${item.campusName} · ${item.name}`" :value="item.id" />
          </el-select>
        </el-form-item>
        <div v-if="active === 'classrooms'" class="form-grid">
          <el-form-item label="容量"><el-input-number v-model="form.capacity" :min="1" :max="1000" /></el-form-item>
          <el-form-item label="教室类型"><el-input v-model="form.roomType" /></el-form-item>
        </div>
        <el-form-item v-if="active === 'classrooms'" label="教学场地性质" required>
          <el-checkbox-group v-model="form.teachingVenueNatures">
            <el-checkbox v-for="item in venueNatureOptions" :key="item.value" :value="item.value">{{ item.label }}</el-checkbox>
          </el-checkbox-group>
        </el-form-item>
        <el-form-item v-if="active === 'classrooms'" label="设备"><el-input v-model="form.equipment" /></el-form-item>
        <div class="form-grid compact">
          <el-form-item label="排序"><el-input-number v-model="form.sortOrder" :min="0" /></el-form-item>
          <el-form-item label="状态"><el-switch v-model="form.isEnabled" active-text="启用" inactive-text="停用" /></el-form-item>
        </div>
      </el-form>
      <template #footer>
        <el-button @click="dialogVisible = false">取消</el-button>
        <el-button type="primary" @click="save">保存</el-button>
      </template>
    </el-dialog>
  </div>
</template>
