<template>
  <div class="tag-mgmt-page">
    <a-card class="title-card">
      <template #title>标签管理</template>
      <template #extra>
        <a-button type="primary" @click="openModal()">
          <template #icon><PlusOutlined /></template>
          新增标签
        </a-button>
      </template>
    </a-card>

    <!-- 按分类分组展示 -->
    <div v-if="loading" class="loading-wrap"><a-spin /></div>

    <template v-else>
      <div v-for="group in groupedTags" :key="group.category" class="category-group">
        <div class="category-header">
          <span class="category-name">
            <span class="category-dot" :style="{ background: group.color }"></span>
            {{ group.category }}
          </span>
          <span class="category-count">{{ group.tags.length }} 个标签</span>
        </div>
        <div class="tag-grid">
          <div
            v-for="(tag, idx) in group.tags"
            :key="tag.id"
            class="tag-card"
            :class="{ disabled: tag.status === 'disabled' }"
          >
            <!-- 预览色条 -->
            <div class="tag-color-bar" :style="{ background: tag.color || group.color }"></div>
            <div class="tag-body">
              <div class="tag-main">
                <span class="tag-name">{{ tag.name }}</span>
                <a-tag v-if="tag.status === 'disabled'" color="red" style="margin-left: 6px; font-size: 10px">已禁用</a-tag>
              </div>
              <div class="tag-meta">
                <span
                  class="tag-usage"
                  :class="{ clickable: tag.usageCount > 0 }"
                  @click="tag.usageCount > 0 && goToWorks(tag.name)"
                >
                  {{ tag.usageCount }} 次使用
                </span>
                <span class="tag-sort">排序: {{ tag.sort }}</span>
              </div>
              <!-- 预览效果 -->
              <div class="tag-preview">
                <span class="preview-label">用户端预览：</span>
                <a-tag :color="tag.color || group.color">{{ tag.name }}</a-tag>
              </div>
              <div class="tag-actions">
                <!-- 排序按钮 -->
                <a-button type="text" size="small" :disabled="idx === 0" @click="moveTag(group, idx, -1)">
                  <up-outlined />
                </a-button>
                <a-button type="text" size="small" :disabled="idx === group.tags.length - 1" @click="moveTag(group, idx, 1)">
                  <down-outlined />
                </a-button>
                <a-button type="link" size="small" @click="openModal(tag)">编辑</a-button>
                <a-button type="link" size="small" @click="handleToggle(tag)">
                  {{ tag.status === 'enabled' ? '禁用' : '启用' }}
                </a-button>
                <a-popconfirm title="确定删除？" @confirm="handleDelete(tag.id)">
                  <a-button type="link" danger size="small" :disabled="tag.usageCount > 0">删除</a-button>
                </a-popconfirm>
              </div>
            </div>
          </div>
        </div>
      </div>

      <!-- 未分类 -->
      <div v-if="uncategorizedTags.length > 0" class="category-group">
        <div class="category-header">
          <span class="category-name">
            <span class="category-dot" style="background: #9ca3af"></span>
            未分类
          </span>
          <span class="category-count">{{ uncategorizedTags.length }} 个标签</span>
        </div>
        <div class="tag-grid">
          <div
            v-for="tag in uncategorizedTags"
            :key="tag.id"
            class="tag-card"
            :class="{ disabled: tag.status === 'disabled' }"
          >
            <div class="tag-color-bar" :style="{ background: tag.color || '#9ca3af' }"></div>
            <div class="tag-body">
              <div class="tag-main">
                <span class="tag-name">{{ tag.name }}</span>
                <a-tag v-if="tag.status === 'disabled'" color="red" style="margin-left: 6px; font-size: 10px">已禁用</a-tag>
              </div>
              <div class="tag-meta">
                <span class="tag-usage" :class="{ clickable: tag.usageCount > 0 }" @click="tag.usageCount > 0 && goToWorks(tag.name)">{{ tag.usageCount }} 次使用</span>
              </div>
              <div class="tag-preview">
                <span class="preview-label">用户端预览：</span>
                <a-tag :color="tag.color || '#9ca3af'">{{ tag.name }}</a-tag>
              </div>
              <div class="tag-actions">
                <a-button type="link" size="small" @click="openModal(tag)">编辑</a-button>
                <a-button type="link" size="small" @click="handleToggle(tag)">{{ tag.status === 'enabled' ? '禁用' : '启用' }}</a-button>
                <a-popconfirm title="确定删除？" @confirm="handleDelete(tag.id)">
                  <a-button type="link" danger size="small" :disabled="tag.usageCount > 0">删除</a-button>
                </a-popconfirm>
              </div>
            </div>
          </div>
        </div>
      </div>

      <div v-if="tags.length === 0" class="empty-wrap">
        <a-empty description="暂无标签" />
      </div>
    </template>

    <!-- 新增/编辑弹窗 -->
    <a-modal v-model:open="modalVisible" :title="editingId ? '编辑标签' : '新增标签'" :footer="null" :width="440">
      <a-form :model="form" layout="vertical" @finish="handleSubmit" style="margin-top: 16px">
        <a-form-item label="标签名称" :rules="[{ required: true, message: '请输入' }]">
          <a-input v-model:value="form.name" placeholder="如：童话、科幻、自然" />
        </a-form-item>
        <a-form-item label="所属分类" :rules="[{ required: true, message: '请选择分类' }]">
          <a-select
            v-model:value="form.category"
            placeholder="选择或输入新分类"
            :options="categoryOptions"
            show-search
            allow-clear
            :filter-option="false"
            @search="onCategorySearch"
          >
            <template #notFoundContent>
              <div v-if="categorySearchVal" style="padding: 4px 8px; font-size: 12px; color: #6b7280; cursor: pointer" @click="form.category = categorySearchVal">
                创建分类「{{ categorySearchVal }}」
              </div>
              <span v-else style="color: #9ca3af">请输入分类名</span>
            </template>
          </a-select>
        </a-form-item>
        <a-form-item label="标签颜色">
          <div class="color-picker-row">
            <span
              v-for="c in presetColors"
              :key="c"
              :class="['color-dot', { active: form.color === c }]"
              :style="{ background: c }"
              @click="form.color = c"
            ></span>
            <a-input v-model:value="form.color" placeholder="#6366f1" style="width: 100px; margin-left: 8px" size="small" />
          </div>
        </a-form-item>
        <a-form-item label="排序权重">
          <a-input-number v-model:value="form.sort" :min="0" style="width: 100%" placeholder="数字越小越靠前" />
        </a-form-item>

        <!-- 实时预览 -->
        <div class="form-preview">
          <span class="preview-label">用户端预览效果：</span>
          <a-tag :color="form.color || '#6366f1'">{{ form.name || '标签名称' }}</a-tag>
        </div>

        <a-button type="primary" html-type="submit" block :loading="submitting" style="margin-top: 16px">保存</a-button>
      </a-form>
    </a-modal>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, computed, onMounted } from 'vue'
import { useRouter } from 'vue-router'
import { message } from 'ant-design-vue'
import { PlusOutlined, UpOutlined, DownOutlined } from '@ant-design/icons-vue'
import request from '@/utils/request'

const router = useRouter()
const tags = ref<any[]>([])
const categories = ref<string[]>([])
const loading = ref(false)
const modalVisible = ref(false)
const submitting = ref(false)
const editingId = ref<number | null>(null)
const form = reactive({ name: '', category: '', color: '', sort: 0 })
const categorySearchVal = ref('')

const presetColors = ['#6366f1', '#ec4899', '#10b981', '#f59e0b', '#ef4444', '#3b82f6', '#8b5cf6', '#14b8a6', '#f97316', '#64748b']

// 分类下拉选项（已有分类 + 搜索输入）
const categoryOptions = computed(() => {
  const opts = categories.value.map(c => ({ label: c, value: c }))
  if (categorySearchVal.value && !categories.value.includes(categorySearchVal.value)) {
    opts.push({ label: `创建「${categorySearchVal.value}」`, value: categorySearchVal.value })
  }
  return opts
})

const onCategorySearch = (val: string) => { categorySearchVal.value = val }

// 按分类分组（#1）
const categoryColorMap: Record<string, string> = {}
const groupedTags = computed(() => {
  const groups: Record<string, { category: string; color: string; tags: any[] }> = {}
  for (const tag of tags.value) {
    if (!tag.category) continue
    if (!groups[tag.category]) {
      // 取该分类下第一个有颜色的标签作为分类颜色
      const color = tag.color || '#6366f1'
      groups[tag.category] = { category: tag.category, color, tags: [] }
    }
    groups[tag.category].tags.push(tag)
  }
  return Object.values(groups)
})

const uncategorizedTags = computed(() => tags.value.filter(t => !t.category))

const fetchTags = async () => {
  loading.value = true
  try { tags.value = await request.get('/tags') as any } catch { message.error('获取失败') }
  finally { loading.value = false }
}

const fetchCategories = async () => {
  try { categories.value = await request.get('/tags/categories') as any } catch { /* */ }
}

const openModal = (record?: any) => {
  editingId.value = record?.id || null
  form.name = record?.name || ''
  form.category = record?.category || ''
  form.color = record?.color || ''
  form.sort = record?.sort || 0
  categorySearchVal.value = ''
  modalVisible.value = true
}

const handleSubmit = async () => {
  submitting.value = true
  try {
    if (editingId.value) {
      await request.put(`/tags/${editingId.value}`, form)
      message.success('编辑成功')
    } else {
      await request.post('/tags', form)
      message.success('创建成功')
    }
    modalVisible.value = false
    fetchTags()
    fetchCategories()
  } catch (e: any) { message.error(e?.response?.data?.message || '操作失败') }
  finally { submitting.value = false }
}

const handleToggle = async (record: any) => {
  try {
    await request.patch(`/tags/${record.id}/status`)
    message.success(record.status === 'enabled' ? '已禁用' : '已启用')
    fetchTags()
  } catch { message.error('操作失败') }
}

const handleDelete = async (id: number) => {
  try { await request.delete(`/tags/${id}`); message.success('删除成功'); fetchTags() }
  catch (e: any) { message.error(e?.response?.data?.message || '删除失败') }
}

// #4 拖拽排序（上移/下移）
const moveTag = async (group: { tags: any[] }, idx: number, direction: number) => {
  const targetIdx = idx + direction
  if (targetIdx < 0 || targetIdx >= group.tags.length) return

  // 交换排序值
  const a = group.tags[idx]
  const b = group.tags[targetIdx]
  const tmpSort = a.sort
  a.sort = b.sort
  b.sort = tmpSort

  // 如果排序值相同则用索引强制区分
  if (a.sort === b.sort) {
    a.sort = targetIdx
    b.sort = idx
  }

  // 交换位置
  ;[group.tags[idx], group.tags[targetIdx]] = [group.tags[targetIdx], group.tags[idx]]

  try {
    await request.post('/tags/batch-sort', {
      items: [
        { id: a.id, sort: a.sort },
        { id: b.id, sort: b.sort },
      ],
    })
  } catch {
    message.error('排序保存失败')
    fetchTags()
  }
}

// #5 使用次数点击跳转作品管理页
const goToWorks = (tagName: string) => {
  // 跳转到作品管理页，带标签名作为搜索关键词
  router.push({ path: '/content/management', query: { keyword: tagName } })
}

onMounted(() => { fetchTags(); fetchCategories() })
</script>

<style scoped lang="scss">
$primary: #6366f1;
.title-card { margin-bottom: 16px; border: none; border-radius: 12px; box-shadow: 0 2px 12px rgba(0,0,0,0.06);
  :deep(.ant-card-head) { border-bottom: none; .ant-card-head-title { font-size: 18px; font-weight: 600; } }
  :deep(.ant-card-body) { padding: 0; }
}

.loading-wrap { padding: 60px 0; display: flex; justify-content: center; }
.empty-wrap { padding: 60px 0; display: flex; justify-content: center; }

// 分类分组
.category-group {
  margin-bottom: 20px;
  background: #fff;
  border-radius: 12px;
  box-shadow: 0 2px 12px rgba(0,0,0,0.06);
  overflow: hidden;
}

.category-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 14px 20px;
  background: #fafafa;
  border-bottom: 1px solid #f0f0f0;

  .category-name {
    display: flex; align-items: center; gap: 8px;
    font-size: 15px; font-weight: 600; color: #1e1b4b;
  }
  .category-dot { width: 10px; height: 10px; border-radius: 50%; flex-shrink: 0; }
  .category-count { font-size: 12px; color: #9ca3af; }
}

.tag-grid { padding: 12px 16px; display: flex; flex-direction: column; gap: 8px; }

.tag-card {
  display: flex;
  border: 1px solid rgba($primary, 0.06);
  border-radius: 10px;
  overflow: hidden;
  transition: all 0.2s;

  &:hover { box-shadow: 0 2px 12px rgba($primary, 0.08); }
  &.disabled { opacity: 0.55; }

  .tag-color-bar { width: 4px; flex-shrink: 0; }

  .tag-body {
    flex: 1; padding: 10px 14px;
    display: flex; align-items: center; gap: 16px; flex-wrap: wrap;

    .tag-main { display: flex; align-items: center; min-width: 100px; }
    .tag-name { font-size: 14px; font-weight: 600; color: #1e1b4b; }

    .tag-meta {
      display: flex; gap: 12px;
      .tag-usage { font-size: 12px; color: #9ca3af;
        &.clickable { color: $primary; cursor: pointer; &:hover { text-decoration: underline; } }
      }
      .tag-sort { font-size: 12px; color: #d1d5db; }
    }

    .tag-preview {
      display: flex; align-items: center; gap: 6px;
      .preview-label { font-size: 11px; color: #d1d5db; }
    }

    .tag-actions {
      margin-left: auto;
      display: flex; align-items: center; gap: 2px;
    }
  }
}

// 颜色选择器
.color-picker-row {
  display: flex; align-items: center; gap: 6px; flex-wrap: wrap;

  .color-dot {
    width: 24px; height: 24px; border-radius: 50%; cursor: pointer;
    border: 2px solid transparent; transition: all 0.2s;

    &:hover { transform: scale(1.15); }
    &.active { border-color: #1e1b4b; box-shadow: 0 0 0 2px rgba(0,0,0,0.1); }
  }
}

// 弹窗预览
.form-preview {
  display: flex; align-items: center; gap: 8px;
  padding: 12px 16px;
  background: #fafafa;
  border-radius: 8px;

  .preview-label { font-size: 12px; color: #9ca3af; }
}
</style>
