<script setup lang="ts">
import { useRouteGroupStore } from '@/stores/route-group'
import type { RouteGroupRecord, RouteTreeNode } from '@/stores/route-group'
import {
  PlusOutlined,
  EditOutlined,
  DeleteOutlined,
  SaveOutlined,
  SyncOutlined,
} from '@ant-design/icons-vue'

const groupStore = useRouteGroupStore()

// 路由组表单
const modalOpen = ref(false)
const modalTitle = ref('新建路由组')
const editingGroupId = ref<number | null>(null)
const formState = reactive({
  name: '',
  label: '',
  description: '',
  sort_order: 0,
})
const saving = ref(false)

// method 颜色映射
const methodColorMap: Record<string, string> = {
  GET: 'green',
  POST: 'blue',
  PUT: 'orange',
  DELETE: 'red',
  PATCH: 'cyan',
}

const routeColumns = [
  { title: '方法', key: 'method', width: 100 },
  { title: '路径', dataIndex: 'path', key: 'path' },
  { title: '描述', dataIndex: 'description', key: 'description', width: 200 },
  { title: '所属组', key: 'group', width: 180 },
]

// 组选项（含"无"选项）
const groupOptions = computed(() => [
  { value: null as number | null, label: '无（未分组）' },
  ...groupStore.groups.map((g) => ({ value: g.id, label: g.label || g.name })),
])

// 筛选未分组路由
const ungroupedRoutes = computed(() =>
  groupStore.routes.filter((r) => r.group_id === null),
)

// 树形选择器本地勾选状态
const localCheckedKeys = ref<{ checked: (string | number)[], halfChecked: (string | number)[] }>({
  checked: [],
  halfChecked: [],
})
const assignSaving = ref(false)
const syncing = ref(false)

// 当前选中组的名称
const selectedGroupName = computed(() => {
  if (typeof groupStore.selectedGroupId !== 'number') return ''
  const g = groupStore.groups.find((g) => g.id === groupStore.selectedGroupId)
  return g ? (g.label || g.name) : ''
})

// 切换路由组时重置 checkedKeys
watch(
  () => groupStore.selectedGroupId,
  () => {
    localCheckedKeys.value = {
      checked: [...groupStore.checkedRouteKeys],
      halfChecked: [],
    }
  },
)

// 保存路由分配
async function handleSaveAssignment() {
  if (typeof groupStore.selectedGroupId !== 'number') return
  assignSaving.value = true
  try {
    const routeIds = localCheckedKeys.value.checked
      .filter((k) => String(k).startsWith('route:'))
      .map((k) => Number(String(k).replace('route:', '')))
    await groupStore.batchAssignRoutes(groupStore.selectedGroupId, routeIds)
    message.success('路由分配保存成功')
  } catch (err: unknown) {
    const msg = err instanceof Error ? err.message : '保存失败'
    message.error(msg)
  } finally {
    assignSaving.value = false
  }
}

function selectGroup(id: number | null | 'ungrouped') {
  groupStore.selectedGroupId = id
}

function openCreateModal() {
  editingGroupId.value = null
  modalTitle.value = '新建路由组'
  formState.name = ''
  formState.label = ''
  formState.description = ''
  formState.sort_order = 0
  modalOpen.value = true
}

function openEditModal(group: RouteGroupRecord) {
  editingGroupId.value = group.id
  modalTitle.value = '编辑路由组'
  formState.name = group.name
  formState.label = group.label
  formState.description = group.description
  formState.sort_order = group.sort_order
  modalOpen.value = true
}

async function handleSubmit() {
  saving.value = true
  try {
    if (editingGroupId.value) {
      await groupStore.updateGroup(editingGroupId.value, { ...formState })
      message.success('路由组更新成功')
    } else {
      await groupStore.createGroup({ ...formState })
      message.success('路由组创建成功')
    }
    modalOpen.value = false
  } catch (err: unknown) {
    const msg = err instanceof Error ? err.message : '操作失败'
    message.error(msg)
  } finally {
    saving.value = false
  }
}

async function handleDelete(group: RouteGroupRecord) {
  try {
    await groupStore.deleteGroup(group.id)
    if (groupStore.selectedGroupId === group.id) {
      groupStore.selectedGroupId = null
    }
    message.success('路由组删除成功')
  } catch (err: unknown) {
    const msg = err instanceof Error ? err.message : '删除失败'
    message.error(msg)
  }
}

async function handleSyncRoutes() {
  syncing.value = true
  try {
    await groupStore.syncRoutes()
    message.success('路由同步成功')
  } catch (err: unknown) {
    const msg = err instanceof Error ? err.message : '同步失败'
    message.error(msg)
  } finally {
    syncing.value = false
  }
}

async function handleGroupChange(routeId: number, groupId: number | null) {
  try {
    await groupStore.assignRouteToGroup(routeId, groupId)
    await groupStore.fetchRoutes()
    await groupStore.fetchGroups()
    message.success('路由分配成功')
  } catch (err: unknown) {
    const msg = err instanceof Error ? err.message : '分配失败'
    message.error(msg)
  }
}

onMounted(async () => {
  await Promise.all([groupStore.fetchGroups(), groupStore.fetchRoutes()])
})
</script>

<template>
  <a-row :gutter="16">
    <!-- 左侧：路由组列表 -->
    <a-col :span="8">
      <a-card title="路由组" :loading="groupStore.loading">
        <template #extra>
          <a-space>
            <a-button size="small" :loading="syncing" @click="handleSyncRoutes">
              <SyncOutlined /> 同步路由
            </a-button>
            <a-button type="primary" size="small" @click="openCreateModal">
              <PlusOutlined /> 新建
            </a-button>
          </a-space>
        </template>

        <!-- 未分组入口 -->
        <div
          class="cursor-pointer px-3 py-2 rounded mb-1"
          :class="groupStore.selectedGroupId === 'ungrouped' ? 'bg-blue-50' : 'hover:bg-gray-50'"
          @click="selectGroup('ungrouped')"
        >
          <div class="font-medium">未分组</div>
          <div class="text-xs text-gray-400">未归入任何路由组的路由</div>
        </div>

        <a-divider class="my-2" />

        <!-- 路由组列表 -->
        <div
          v-for="group in groupStore.groups"
          :key="group.id"
          class="cursor-pointer px-3 py-2 rounded mb-1 flex items-center justify-between"
          :class="groupStore.selectedGroupId === group.id ? 'bg-blue-50' : 'hover:bg-gray-50'"
          @click="selectGroup(group.id)"
        >
          <div>
            <div class="font-medium">{{ group.label || group.name }}</div>
            <div class="text-xs text-gray-400">{{ group.route_count ?? 0 }} 条路由</div>
          </div>
          <div class="flex gap-1" @click.stop>
            <a-button type="text" size="small" @click="openEditModal(group)">
              <EditOutlined />
            </a-button>
            <a-popconfirm
              title="删除后，关联的角色授权将受影响，确认删除？"
              @confirm="handleDelete(group)"
            >
              <a-button type="text" size="small" danger>
                <DeleteOutlined />
              </a-button>
            </a-popconfirm>
          </div>
        </div>
      </a-card>
    </a-col>

    <!-- 右侧：条件渲染 -->
    <a-col :span="16">
      <!-- 状态1: 未选中路由组 -->
      <a-card v-if="groupStore.selectedGroupId === null" title="路由列表">
        <a-empty description="请选择路由组" />
      </a-card>

      <!-- 状态2: 未分组路由表格 -->
      <a-card v-else-if="groupStore.selectedGroupId === 'ungrouped'" title="未分组路由">
        <a-table
          :columns="routeColumns"
          :data-source="ungroupedRoutes"
          :loading="groupStore.routesLoading"
          :pagination="false"
          row-key="id"
          size="small"
        >
          <template #bodyCell="{ column, record }">
            <template v-if="column.key === 'method'">
              <a-tag :color="methodColorMap[record.method] || 'default'">
                {{ record.method }}
              </a-tag>
            </template>
            <template v-if="column.key === 'group'">
              <a-select
                :value="record.group_id"
                :options="groupOptions"
                size="small"
                style="width: 150px"
                placeholder="选择路由组"
                @change="(val: unknown) => handleGroupChange(record.id, val as number | null)"
              />
            </template>
          </template>
        </a-table>
      </a-card>

      <!-- 状态3: 路由组树形选择器 -->
      <a-card v-else :title="selectedGroupName">
        <template #extra>
          <a-button
            type="primary"
            size="small"
            :loading="assignSaving"
            @click="handleSaveAssignment"
          >
            <SaveOutlined /> 保存分配
          </a-button>
        </template>

        <a-tree
          v-model:checkedKeys="localCheckedKeys"
          checkable
          :check-strictly="true"
          :tree-data="groupStore.routeTree"
          :selectable="false"
          default-expand-all
        >
          <template #title="node">
            <template v-if="(node as RouteTreeNode).isLeaf">
              <a-tag :color="methodColorMap[(node as RouteTreeNode).method!] || 'default'" class="mr-1">
                {{ (node as RouteTreeNode).method }}
              </a-tag>
              <span class="text-gray-600">{{ (node as RouteTreeNode).title }}</span>
            </template>
            <template v-else>
              <span class="font-medium">{{ (node as RouteTreeNode).title }}</span>
            </template>
          </template>
        </a-tree>
      </a-card>
    </a-col>
  </a-row>

  <!-- 路由组新建/编辑 Modal -->
  <a-modal
    v-model:open="modalOpen"
    :title="modalTitle"
    :confirm-loading="saving"
    @ok="handleSubmit"
  >
    <a-form :label-col="{ span: 6 }" :wrapper-col="{ span: 16 }" class="mt-4">
      <a-form-item label="组标识" required>
        <a-input v-model:value="formState.name" placeholder="如 user-management" />
      </a-form-item>
      <a-form-item label="显示名称" required>
        <a-input v-model:value="formState.label" placeholder="如 用户管理" />
      </a-form-item>
      <a-form-item label="描述">
        <a-textarea v-model:value="formState.description" :rows="2" />
      </a-form-item>
      <a-form-item label="排序">
        <a-input-number v-model:value="formState.sort_order" :min="0" />
      </a-form-item>
    </a-form>
  </a-modal>
</template>
