<script setup lang="ts">
import { ref, onMounted, computed } from 'vue'
import {
  getTypeList,
  updateType,
  deleteType,
  createType,
  searchCourses,
  getAllLabels,
  createLabel,
  getLabelsByTypeId,
  addLabelsToType,
  removeLabelFromType,
  removeLabelsFromType,
  type CourseType,
  type CourseLabel,
  type CourseSearchParams,
  type GroupCourse,
} from '@/api/groupCourse'
import AppLayout from '@/components/AppLayout.vue'
import { useToast } from '@/composables/useToast'
import { useAuthStore } from '@/stores/auth'

const toast = useToast()
const authStore = useAuthStore()

// --- 类型列表 ---
const types = ref<CourseType[]>([])
const loadingTypes = ref(false)
const selectedTypeId = ref<number | null>(null)

// --- 排序 ---
const sortField = ref<string>('id')
const sortDirection = ref<string>('asc')
const sortOptions = [
  { label: 'ID 升序', field: 'id', direction: 'asc' },
  { label: 'ID 降序', field: 'id', direction: 'desc' },
  { label: '创建时间 升序', field: 'createTime', direction: 'asc' },
  { label: '创建时间 降序', field: 'createTime', direction: 'desc' },
  { label: '修改时间 升序', field: 'updateTime', direction: 'asc' },
  { label: '修改时间 降序', field: 'updateTime', direction: 'desc' },
]

// --- 类型编辑 ---
const editingType = ref(false)
const typeForm = ref({ typeName: '', description: '', category: '' })
const saveTypeLoading = ref(false)

// --- 类型创建 ---
const showCreateModal = ref(false)
const createForm = ref({ typeName: '', description: '', category: '', baseDifficulty: 1 })
const createLoading = ref(false)

// --- 标签管理 ---
const typeLabels = ref<CourseLabel[]>([])
const allLabels = ref<CourseLabel[]>([])
const loadingLabels = ref(false)
const showLabelModal = ref(false)
const addLabelIds = ref<number[]>([])
const batchDeleteMode = ref(false)
const batchSelectedLabelIds = ref<number[]>([])

// --- 新建标签 ---
const newLabelForm = ref({ labelName: '', color: '#1890ff' })
const createLabelLoading = ref(false)

// --- 删除确认弹窗 ---
const showDeleteModal = ref(false)
const deleteTargetId = ref<number | null>(null)
const deleteTargetName = ref('')
const deletePassword = ref('')
const deleteLoading = ref(false)
const deleteError = ref('')

// --- 该类型下的团课 ---
const typeCourses = ref<GroupCourse[]>([])
const loadingCourses = ref(false)

const selectedType = computed(() => types.value.find((t) => t.id === selectedTypeId.value))

async function fetchTypes() {
  loadingTypes.value = true
  try {
    types.value = await getTypeList(true, sortField.value, sortDirection.value)
    // 默认选中第一个
    const first = types.value[0]
    if (first && !selectedTypeId.value) {
      selectedTypeId.value = first.id
      await loadTypeDetail(first.id)
    }
  } catch {
    types.value = []
  } finally {
    loadingTypes.value = false
  }
}

function handleSortChange(field: string, direction: string) {
  sortField.value = field
  sortDirection.value = direction
  fetchTypes()
}

function onSortChange(value: string) {
  const parts = value.split('-')
  handleSortChange(parts[0]!, parts[1] || '')
}

async function selectType(id: number) {
  selectedTypeId.value = id
  await loadTypeDetail(id)
}

async function loadTypeDetail(id: number) {
  await Promise.all([fetchTypeLabels(id), fetchTypeCourses(id)])
}

async function fetchTypeLabels(typeId: number) {
  loadingLabels.value = true
  try {
    typeLabels.value = await getLabelsByTypeId(typeId)
  } catch {
    typeLabels.value = []
  } finally {
    loadingLabels.value = false
  }
}

async function fetchTypeCourses(typeId: number) {
  loadingCourses.value = true
  try {
    const res = await searchCourses({ courseType: typeId, size: 100 })
    typeCourses.value = res.data?.content || []
  } catch {
    typeCourses.value = []
  } finally {
    loadingCourses.value = false
  }
}

function startEditType() {
  const t = selectedType.value
  if (!t) return
  typeForm.value = {
    typeName: t.typeName,
    description: t.description || '',
    category: t.category || '',
  }
  editingType.value = true
}

function cancelEditType() {
  editingType.value = false
}

async function handleSaveType() {
  if (!selectedTypeId.value) return
  saveTypeLoading.value = true
  try {
    await updateType(selectedTypeId.value, typeForm.value)
    toast.success('类型更新成功')
    editingType.value = false
    await fetchTypes()
  } catch (e: any) {
    toast.error(e?.response?.data?.message || '更新失败')
  } finally {
    saveTypeLoading.value = false
  }
}

function openDeleteModal(id: number, name: string) {
  deleteTargetId.value = id
  deleteTargetName.value = name
  deletePassword.value = ''
  deleteError.value = ''
  showDeleteModal.value = true
}

async function handleDeleteType() {
  if (!deleteTargetId.value || !deletePassword.value.trim()) {
    deleteError.value = '请输入管理员密码'
    return
  }
  deleteLoading.value = true
  deleteError.value = ''
  try {
    await deleteType(deleteTargetId.value, deletePassword.value)
    toast.success('类型已删除')
    showDeleteModal.value = false
    if (selectedTypeId.value === deleteTargetId.value) {
      selectedTypeId.value = null
    }
    await fetchTypes()
  } catch (e: any) {
    deleteError.value = e?.response?.data?.message || '删除失败'
  } finally {
    deleteLoading.value = false
  }
}

async function handleCreateType() {
  if (!createForm.value.typeName.trim()) {
    toast.error('类型名称不能为空')
    return
  }
  createLoading.value = true
  try {
    await createType(createForm.value)
    toast.success('类型创建成功')
    showCreateModal.value = false
    createForm.value = { typeName: '', description: '', category: '', baseDifficulty: 1 }
    await fetchTypes()
  } catch (e: any) {
    toast.error(e?.response?.data?.message || '创建失败')
  } finally {
    createLoading.value = false
  }
}

async function openLabelModal() {
  addLabelIds.value = []
  try {
    allLabels.value = await getAllLabels()
  } catch {
    allLabels.value = []
  }
  showLabelModal.value = true
}

function toggleLabelSelection(id: number) {
  const idx = addLabelIds.value.indexOf(id)
  if (idx >= 0) {
    addLabelIds.value.splice(idx, 1)
  } else {
    addLabelIds.value.push(id)
  }
}

async function handleAddLabels() {
  if (!selectedTypeId.value || addLabelIds.value.length === 0) return
  try {
    await addLabelsToType(selectedTypeId.value, addLabelIds.value)
    toast.success('标签添加成功')
    showLabelModal.value = false
    await fetchTypeLabels(selectedTypeId.value)
  } catch (e: any) {
    toast.error(e?.response?.data?.message || '添加失败')
  }
}

async function handleCreateNewLabel() {
  if (!newLabelForm.value.labelName.trim()) {
    toast.error('标签名称不能为空')
    return
  }
  createLabelLoading.value = true
  try {
    const res = await createLabel({
      labelName: newLabelForm.value.labelName.trim(),
      color: newLabelForm.value.color || '#1890ff',
    })
    toast.success('标签创建成功')
    // 刷新标签列表
    allLabels.value = await getAllLabels()
    // 自动选中新创建的标签
    if (res.data?.id) {
      addLabelIds.value.push(res.data.id)
    }
    newLabelForm.value = { labelName: '', color: '#1890ff' }
  } catch (e: any) {
    toast.error(e?.response?.data?.message || '创建失败')
  } finally {
    createLabelLoading.value = false
  }
}

async function handleRemoveLabel(labelId: number) {
  if (!selectedTypeId.value) return
  try {
    await removeLabelFromType(selectedTypeId.value, labelId)
    toast.success('标签已移除')
    await fetchTypeLabels(selectedTypeId.value)
  } catch (e: any) {
    toast.error(e?.response?.data?.message || '移除失败')
  }
}

function enterBatchDeleteMode() {
  batchDeleteMode.value = true
  batchSelectedLabelIds.value = []
}

function cancelBatchDelete() {
  batchDeleteMode.value = false
  batchSelectedLabelIds.value = []
}

function toggleBatchLabelSelection(id: number) {
  const idx = batchSelectedLabelIds.value.indexOf(id)
  if (idx >= 0) {
    batchSelectedLabelIds.value.splice(idx, 1)
  } else {
    batchSelectedLabelIds.value.push(id)
  }
}

async function handleBatchRemoveLabels() {
  if (!selectedTypeId.value || batchSelectedLabelIds.value.length === 0) return
  try {
    await removeLabelsFromType(selectedTypeId.value, batchSelectedLabelIds.value)
    toast.success(`已移除 ${batchSelectedLabelIds.value.length} 个标签`)
    batchDeleteMode.value = false
    batchSelectedLabelIds.value = []
    await fetchTypeLabels(selectedTypeId.value)
  } catch (e: any) {
    toast.error(e?.response?.data?.message || '批量移除失败')
  }
}

function formatTime(t: string) {
  if (!t) return '--'
  return new Date(t).toLocaleString('zh-CN')
}

function getCourseStatusText(c: GroupCourse): string {
  if (c.deletedAt) return '已删除'
  const s = Number(c.status)
  if (s === 0) return '正常'
  if (s === 1) return '已取消'
  if (s === 2) return '已结束'
  return '未知'
}

// 可用标签（排除已添加的）
const availableLabels = computed(() =>
  allLabels.value.filter((l) => !typeLabels.value.some((tl) => tl.id === l.id)),
)

onMounted(fetchTypes)
</script>

<template>
  <AppLayout>
    <div class="type-page">
      <!-- 左侧：类型列表 -->
      <div class="type-sidebar">
        <div class="sidebar-header">
          <h3>课程类型</h3>
          <button class="btn-icon" v-if="authStore.hasPermission('business:groupCourseType:create')" @click="showCreateModal = true" title="新建类型">
            <i class="fas fa-plus"></i>
          </button>
        </div>
        <div class="sidebar-sort">
          <select
            class="sort-select"
            :value="`${sortField}-${sortDirection}`"
            @change="(e) => onSortChange((e.target as HTMLSelectElement).value)"
          >
            <option
              v-for="opt in sortOptions"
              :key="opt.field + '-' + opt.direction"
              :value="opt.field + '-' + opt.direction"
            >
              {{ opt.label }}
            </option>
          </select>
        </div>
        <div class="type-list">
          <div v-if="loadingTypes" class="type-list-loading">加载中...</div>
          <div v-else-if="types.length === 0" class="type-list-empty">暂无类型</div>
          <div
            v-for="t in types"
            :key="t.id"
            class="type-item"
            :class="{ active: selectedTypeId === t.id }"
            @click="selectType(t.id)"
          >
            <span class="type-name">{{ t.typeName }}</span>
            <span v-if="t.category" class="type-category">{{ t.category }}</span>
          </div>
        </div>
      </div>

      <!-- 右侧：详情 -->
      <div class="type-detail">
        <template v-if="selectedType">
          <!-- 类型信息卡片 -->
          <div class="detail-card">
            <div class="card-header">
              <h2>{{ selectedType.typeName }}</h2>
              <div class="card-actions">
                <button v-if="!editingType && authStore.hasPermission('business:groupCourseType:edit')" class="btn-sm" @click="startEditType">
                  <i class="fas fa-edit"></i> 编辑
                </button>
                <button
                  v-if="authStore.hasPermission('business:groupCourseType:delete')"
                  class="btn-sm danger"
                  @click="openDeleteModal(selectedType.id, selectedType.typeName)"
                >
                  <i class="fas fa-trash"></i> 删除
                </button>
              </div>
            </div>

            <!-- 编辑模式 -->
            <template v-if="editingType">
              <div class="edit-form">
                <div class="form-group">
                  <label>类型名称</label>
                  <input v-model="typeForm.typeName" placeholder="类型名称" />
                </div>
                <div class="form-group">
                  <label>分类</label>
                  <input v-model="typeForm.category" placeholder="如：有氧、力量、柔韧" />
                </div>
                <div class="form-group">
                  <label>描述</label>
                  <textarea v-model="typeForm.description" placeholder="类型描述" rows="2"></textarea>
                </div>
                <div class="form-actions">
                  <button class="btn-sm" @click="cancelEditType">取消</button>
                  <button class="btn-sm primary" :disabled="saveTypeLoading" @click="handleSaveType">
                    <i v-if="saveTypeLoading" class="fas fa-spinner fa-spin"></i>
                    {{ saveTypeLoading ? '保存中...' : '保存' }}
                  </button>
                </div>
              </div>
            </template>

            <!-- 查看模式 -->
            <template v-else>
              <div class="type-meta">
                <div v-if="selectedType.category" class="meta-item">
                  <span class="meta-label">分类</span>
                  <span class="meta-value">{{ selectedType.category }}</span>
                </div>
                <div v-if="selectedType.description" class="meta-item">
                  <span class="meta-label">描述</span>
                  <span class="meta-value">{{ selectedType.description }}</span>
                </div>
              </div>
            </template>
          </div>

          <!-- 标签管理 -->
          <div class="detail-card">
            <div class="card-header">
              <h3>标签</h3>
              <div class="card-header-actions">
                <button v-if="!batchDeleteMode && authStore.hasPermission('business:groupCourseType:edit')" class="btn-sm" @click="openLabelModal">
                  <i class="fas fa-plus"></i> 添加标签
                </button>
                <button
                  v-if="!batchDeleteMode && typeLabels.length > 0 && authStore.hasPermission('business:groupCourseType:edit')"
                  class="btn-sm danger-outline"
                  @click="enterBatchDeleteMode"
                >
                  <i class="fas fa-trash"></i> 批量删除
                </button>
                <template v-if="batchDeleteMode">
                  <button
                    class="btn-sm danger"
                    :disabled="batchSelectedLabelIds.length === 0"
                    @click="handleBatchRemoveLabels"
                  >
                    删除选中 ({{ batchSelectedLabelIds.length }})
                  </button>
                  <button class="btn-sm" @click="cancelBatchDelete">取消</button>
                </template>
              </div>
            </div>
            <div v-if="loadingLabels" class="section-loading">加载中...</div>
            <div v-else-if="typeLabels.length === 0" class="section-empty">暂无标签</div>
            <div v-else class="label-cloud">
              <span
                v-for="label in typeLabels"
                :key="label.id"
                class="label-tag"
                :class="{ 'label-tag-selectable': batchDeleteMode, 'label-tag-selected': batchSelectedLabelIds.includes(label.id) }"
                :style="{
                  background: batchSelectedLabelIds.includes(label.id) ? (label.color || '#e74c3c') + '22' : (label.color || '#e6f0ff') + '33',
                  borderColor: batchSelectedLabelIds.includes(label.id) ? (label.color || '#e74c3c') : (label.color || '#4f7cff'),
                  cursor: batchDeleteMode ? 'pointer' : 'default'
                }"
                @click="batchDeleteMode && toggleBatchLabelSelection(label.id)"
              >
                <template v-if="batchDeleteMode">
                  <i
                    class="fas"
                    :class="batchSelectedLabelIds.includes(label.id) ? 'fa-check-square' : 'fa-square'"
                    :style="{ color: label.color || '#4f7cff' }"
                  ></i>
                </template>
                <span :style="{ color: label.color || '#4f7cff' }">{{ label.labelName }}</span>
                <template v-if="!batchDeleteMode && authStore.hasPermission('business:groupCourseType:edit')">
                  <i class="fas fa-times" @click="handleRemoveLabel(label.id)"></i>
                </template>
              </span>
            </div>
          </div>

          <!-- 该类型下的团课 -->
          <div class="detail-card courses-card">
            <div class="card-header">
              <h3>该类型团课 ({{ typeCourses.length }})</h3>
            </div>
            <div v-if="loadingCourses" class="section-loading">加载中...</div>
            <div v-else-if="typeCourses.length === 0" class="section-empty">暂无团课</div>
            <div v-else class="table-scroll">
            <table>
              <thead>
                <tr>
                  <th>ID</th>
                  <th>课程名称</th>
                  <th>开始时间</th>
                  <th>地点</th>
                  <th>人数</th>
                  <th>状态</th>
                </tr>
              </thead>
              <tbody>
                <tr v-for="c in typeCourses" :key="c.id">
                  <td>{{ c.id }}</td>
                  <td>{{ c.courseName }}</td>
                  <td>{{ formatTime(c.startTime) }}</td>
                  <td>{{ c.location || '--' }}</td>
                  <td>{{ c.currentMembers }}/{{ c.maxMembers }}</td>
                  <td>
                    <span class="status-badge" :class="{
                      green: Number(c.status) === 0 && !c.deletedAt,
                      orange: Number(c.status) === 1,
                      gray: !!c.deletedAt,
                    }">{{ getCourseStatusText(c) }}</span>
                  </td>
                </tr>
              </tbody>
            </table>
            </div>
          </div>
        </template>

        <!-- 未选中任何类型 -->
        <div v-else class="no-selection">
          <i class="fas fa-tags"></i>
          <p>请从左侧选择一个课程类型</p>
        </div>
      </div>
    </div>

    <!-- 创建类型弹窗 -->
    <div v-if="showCreateModal" class="modal-overlay" @click.self="showCreateModal = false">
      <div class="modal">
        <h3>新建课程类型</h3>
        <div class="form-group">
          <label>类型名称 <span class="required">*</span></label>
          <input v-model="createForm.typeName" placeholder="请输入类型名称" />
        </div>
        <div class="form-group">
          <label>分类</label>
          <input v-model="createForm.category" placeholder="如：有氧、力量、柔韧" />
        </div>
        <div class="form-group">
          <label>基础难度 (1-10)</label>
          <input v-model.number="createForm.baseDifficulty" type="number" min="1" max="10" />
        </div>
        <div class="form-group">
          <label>描述</label>
          <textarea v-model="createForm.description" placeholder="请输入类型描述" rows="2"></textarea>
        </div>
        <div class="modal-actions">
          <button class="btn-sm" @click="showCreateModal = false">取消</button>
          <button class="btn-sm primary" :disabled="createLoading" @click="handleCreateType">
            <i v-if="createLoading" class="fas fa-spinner fa-spin"></i>
            {{ createLoading ? '创建中...' : '创建' }}
          </button>
        </div>
      </div>
    </div>

    <!-- 添加标签弹窗 -->
    <div v-if="showLabelModal" class="modal-overlay" @click.self="showLabelModal = false">
      <div class="modal modal-sm">
        <h3>添加标签到「{{ selectedType?.typeName }}」</h3>
        <div v-if="availableLabels.length === 0" class="section-empty">
          没有可添加的标签
        </div>
        <div v-else class="label-select-list">
          <label
            v-for="label in availableLabels"
            :key="label.id"
            class="label-select-item"
            :class="{ selected: addLabelIds.includes(label.id) }"
          >
            <input
              type="checkbox"
              :checked="addLabelIds.includes(label.id)"
              @change="toggleLabelSelection(label.id)"
            />
            <span
              class="label-dot"
              :style="{ background: label.color || '#4f7cff' }"
            ></span>
            <span>{{ label.labelName }}</span>
          </label>
        </div>
        <div class="new-label-section">
          <div class="new-label-title">创建新标签</div>
          <div class="new-label-form">
            <input
              v-model="newLabelForm.labelName"
              placeholder="标签名称"
              class="new-label-input"
              maxlength="50"
            />
            <input
              v-model="newLabelForm.color"
              type="color"
              class="new-label-color"
            />
            <button
              class="btn-sm primary"
              :disabled="createLabelLoading || !newLabelForm.labelName.trim()"
              @click="handleCreateNewLabel"
            >
              <i v-if="createLabelLoading" class="fas fa-spinner fa-spin"></i>
              {{ createLabelLoading ? '创建中...' : '新建' }}
            </button>
          </div>
        </div>
        <div class="modal-actions">
          <button class="btn-sm" @click="showLabelModal = false">取消</button>
          <button
            class="btn-sm primary"
            :disabled="addLabelIds.length === 0"
            @click="handleAddLabels"
          >
            确认添加 ({{ addLabelIds.length }})
          </button>
        </div>
      </div>
    </div>

    <!-- 删除类型确认弹窗 -->
    <div v-if="showDeleteModal" class="modal-overlay" @click.self="showDeleteModal = false">
      <div class="modal modal-sm">
        <h3>删除课程类型</h3>
        <div class="delete-warning">
          <i class="fas fa-exclamation-triangle"></i>
          <p>确定要删除类型「<strong>{{ deleteTargetName }}</strong>」吗？此操作不可恢复。</p>
        </div>
        <div class="form-group">
          <label>管理员密码 <span class="required">*</span></label>
          <input
            v-model="deletePassword"
            type="password"
            placeholder="请输入您的管理员密码"
            @keyup.enter="handleDeleteType"
          />
        </div>
        <div v-if="deleteError" class="delete-error">{{ deleteError }}</div>
        <div class="modal-actions">
          <button class="btn-sm" @click="showDeleteModal = false">取消</button>
          <button
            class="btn-sm danger"
            :disabled="deleteLoading"
            @click="handleDeleteType"
          >
            <i v-if="deleteLoading" class="fas fa-spinner fa-spin"></i>
            {{ deleteLoading ? '删除中...' : '确认删除' }}
          </button>
        </div>
      </div>
    </div>
  </AppLayout>
</template>

<style scoped>
.type-page {
  display: flex; gap: 20px; height: calc(100vh - 160px); overflow: hidden;
}

/* ---- 左侧 ---- */
.type-sidebar {
  width: 240px; flex-shrink: 0;
  background: white; border-radius: 16px; border: 1px solid #edf2f9;
  display: flex; flex-direction: column; overflow: hidden;
}

.sidebar-header {
  display: flex; justify-content: space-between; align-items: center;
  padding: 16px; border-bottom: 1px solid #f1f5fa;
}

.sidebar-header h3 {
  font-size: 15px; font-weight: 600; color: #0b1a33; margin: 0;
}

.sidebar-sort {
  padding: 8px 12px; border-bottom: 1px solid #f1f5fa;
}

.sort-select {
  width: 100%; padding: 6px 10px; border-radius: 8px;
  border: 1px solid #e2e8f0; font-size: 13px; color: #1e293b;
  background: #f8fafd; outline: none; cursor: pointer;
}

.sort-select:focus {
  border-color: #4f7cff; box-shadow: 0 0 0 3px rgba(79,124,255,0.12);
}

.btn-icon {
  width: 32px; height: 32px; border-radius: 8px; border: 1px solid #e2e8f0;
  background: white; cursor: pointer; display: flex; align-items: center;
  justify-content: center; font-size: 14px; color: #4f7cff; transition: 0.15s;
}

.btn-icon:hover { background: #f0f5ff; }

.type-list {
  flex: 1; overflow-y: auto; padding: 8px;
}

.type-list-loading,
.type-list-empty {
  text-align: center; padding: 24px; font-size: 13px; color: #94a3b8;
}

.type-item {
  padding: 10px 12px; border-radius: 10px; cursor: pointer;
  display: flex; flex-direction: column; gap: 2px; transition: 0.15s;
}

.type-item:hover { background: #f8fafd; }
.type-item.active { background: #eff6ff; }

.type-name { font-size: 14px; font-weight: 500; color: #1e293b; }
.type-item.active .type-name { color: #4f7cff; }
.type-category { font-size: 12px; color: #94a3b8; }

/* ---- 右侧 ---- */
.type-detail {
  flex: 1; display: flex; flex-direction: column; gap: 16px;
  min-width: 0;
}

.detail-card {
  background: white; border-radius: 16px; border: 1px solid #edf2f9;
  padding: 20px; flex-shrink: 0;
}

.detail-card.courses-card {
  flex: 1; display: flex; flex-direction: column; overflow: hidden;
}

.table-scroll {
  flex: 1; overflow-y: auto;
}

.card-header {
  display: flex; justify-content: space-between; align-items: center;
  margin-bottom: 16px;
}

.card-header h2 {
  font-size: 18px; font-weight: 600; color: #0b1a33; margin: 0;
}

.card-header h3 {
  font-size: 15px; font-weight: 600; color: #0b1a33; margin: 0;
}

.card-actions { display: flex; gap: 8px; }

.type-meta {
  display: flex; flex-direction: column; gap: 10px;
}

.meta-item {
  display: flex; gap: 8px; font-size: 14px;
}

.meta-label {
  color: #94a3b8; font-weight: 500; min-width: 48px;
}

.meta-value { color: #1e293b; }

/* ---- 编辑表单 ---- */
.edit-form {
  display: flex; flex-direction: column; gap: 12px;
}

.form-group { margin-bottom: 4px; }
.form-group label {
  display: block; font-size: 13px; font-weight: 600; color: #1e293b; margin-bottom: 4px;
}
.form-group .required { color: #ef4444; }

.form-group input,
.form-group textarea {
  width: 100%; padding: 8px 12px; border-radius: 10px;
  border: 1px solid #e2e8f0; font-size: 14px; outline: none;
  transition: 0.15s; background: #f8fafd; font-family: inherit;
}

.form-group input:focus,
.form-group textarea:focus {
  border-color: #4f7cff; box-shadow: 0 0 0 3px rgba(79,124,255,0.12);
}

.form-actions {
  display: flex; justify-content: flex-end; gap: 8px; margin-top: 4px;
}

/* ---- 标签 ---- */
.label-cloud {
  display: flex; flex-wrap: wrap; gap: 8px;
}

.label-tag {
  padding: 4px 12px; border-radius: 20px; font-size: 13px;
  border: 1px solid; font-weight: 500;
  display: inline-flex; align-items: center; gap: 6px;
}

.label-tag i {
  cursor: pointer; font-size: 10px; opacity: 0.6;
}

.label-tag i:hover { opacity: 1; }

/* ---- 标签选择列表 ---- */
.label-select-list {
  display: flex; flex-direction: column; gap: 6px; max-height: 300px; overflow-y: auto;
}

.label-select-item {
  display: flex; align-items: center; gap: 10px; padding: 8px 10px;
  border-radius: 10px; cursor: pointer; transition: 0.15s; font-size: 14px;
}

.label-select-item:hover { background: #f8fafd; }
.label-select-item.selected { background: #eff6ff; }

.label-select-item input { margin: 0; }

.label-dot {
  width: 10px; height: 10px; border-radius: 50%; flex-shrink: 0;
}

/* ---- 新建标签区域 ---- */
.new-label-section {
  margin-top: 12px; padding-top: 12px; border-top: 1px solid #eef2f8;
}

.new-label-title {
  font-size: 13px; font-weight: 600; color: #4e627c; margin-bottom: 8px;
}

.new-label-form {
  display: flex; align-items: center; gap: 8px;
}

.new-label-input {
  flex: 1; padding: 6px 10px; border-radius: 8px;
  border: 1px solid #e2e8f0; font-size: 13px; outline: none;
  background: #f8fafd; min-width: 0;
}

.new-label-input:focus {
  border-color: #4f7cff; box-shadow: 0 0 0 3px rgba(79,124,255,0.12);
}

.new-label-color {
  width: 36px; height: 32px; border: 1px solid #e2e8f0; border-radius: 8px;
  padding: 2px; cursor: pointer; flex-shrink: 0;
}

/* ---- 表格 ---- */
table {
  width: 100%; border-collapse: collapse; font-size: 13px;
}

th {
  text-align: left; padding: 10px 8px 10px 0;
  font-weight: 600; color: #4e627c; border-bottom: 1px solid #eef2f8;
}

td {
  padding: 12px 8px 12px 0; border-bottom: 1px solid #f1f5fa; color: #1e2f44;
}

tr:last-child td { border-bottom: none; }

.section-loading,
.section-empty {
  text-align: center; padding: 24px; font-size: 13px; color: #94a3b8;
}

.no-selection {
  flex: 1; display: flex; flex-direction: column; align-items: center;
  justify-content: center; color: #94a3b8; gap: 12px;
}

.no-selection i { font-size: 48px; opacity: 0.3; }
.no-selection p { font-size: 14px; margin: 0; }

/* ---- status ---- */
.status-badge {
  padding: 3px 10px; border-radius: 20px; font-size: 12px;
  font-weight: 500; background: #e6f0ff; color: #4f7cff;
}

.status-badge.green { background: #e0f5ec; color: #0b8b5e; }
.status-badge.orange { background: #fff3e0; color: #b26e00; }
.status-badge.gray { background: #f1f5f9; color: #64748b; }

/* ---- btn ---- */
.btn-sm {
  padding: 6px 14px; border-radius: 20px; border: 1px solid #e2e8f0;
  background: white; font-size: 12px; cursor: pointer; transition: 0.15s;
  display: inline-flex; align-items: center; gap: 4px;
}

.btn-sm:hover { background: #f0f5ff; }
.btn-sm.primary {
  background: #4f7cff; border-color: #4f7cff; color: white;
}
.btn-sm.primary:hover:not(:disabled) { background: #3f6ae0; }
.btn-sm.primary:disabled { opacity: 0.6; cursor: not-allowed; }
.btn-sm.danger { color: #ef4444; border-color: #fecaca; }
.btn-sm.danger:hover { background: #fef2f2; }
.btn-sm.danger-outline { color: #ef4444; border-color: #fecaca; }
.btn-sm.danger-outline:hover { background: #fef2f2; }

.card-header-actions { display: flex; gap: 8px; align-items: center; }

.label-tag-selectable { user-select: none; }
.label-tag-selectable:hover { opacity: 0.85; }
.label-tag-selected { }

/* ---- modal ---- */
.modal-overlay {
  position: fixed; inset: 0; background: rgba(0,0,0,0.3);
  display: flex; align-items: center; justify-content: center; z-index: 200;
}

.modal {
  background: white; border-radius: 20px; padding: 28px;
  width: 480px; max-width: 92vw; max-height: 85vh; overflow-y: auto;
  box-shadow: 0 12px 40px rgba(0,0,0,0.12);
}

.modal-sm { width: 400px; }

.modal h3 {
  font-size: 17px; font-weight: 600; color: #0b1a33; margin-bottom: 20px;
}

.delete-warning {
  display: flex; align-items: flex-start; gap: 10px;
  padding: 12px 14px; background: #fff3e0; border-radius: 10px;
  font-size: 13px; color: #b26e00; margin-bottom: 16px;
}

.delete-warning i {
  font-size: 18px; flex-shrink: 0; margin-top: 1px;
}

.delete-warning p { margin: 0; line-height: 1.5; }

.delete-error {
  padding: 8px 12px; background: #fef2f2; border-radius: 8px;
  font-size: 13px; color: #ef4444; margin-top: 8px;
}

.modal-actions {
  display: flex; justify-content: flex-end; gap: 8px; margin-top: 16px;
}
</style>
