import { api } from '@/utils/request'

export interface RouteGroupRecord {
  id: number
  name: string
  label: string
  description: string
  sort_order: number
  route_count: number
}

export interface RouteRecord {
  id: number
  method: string
  path: string
  description: string
  group_id: number | null
  group_name: string | null
}

export interface RouteTreeNode {
  key: string
  title: string
  children?: RouteTreeNode[]
  isLeaf?: boolean
  routeId?: number
  method?: string
  fullPath?: string
}

export const useRouteGroupStore = defineStore('route-group', () => {
  const groups = ref<RouteGroupRecord[]>([])
  const routes = ref<RouteRecord[]>([])
  const loading = ref(false)
  const routesLoading = ref(false)
  const selectedGroupId = ref<number | null | 'ungrouped'>(null)

  async function fetchGroups() {
    loading.value = true
    try {
      const data = await api.get<RouteGroupRecord[]>('/api/v1/route-groups')
      groups.value = data
    } catch (err: unknown) {
      const msg = err instanceof Error ? err.message : '获取路由组列表失败'
      message.error(msg)
    } finally {
      loading.value = false
    }
  }

  async function createGroup(data: Partial<RouteGroupRecord>) {
    await api.post('/api/v1/route-groups', data)
    await fetchGroups()
  }

  async function updateGroup(id: number, data: Partial<RouteGroupRecord>) {
    await api.put(`/api/v1/route-groups/${id}`, data)
    await fetchGroups()
  }

  async function deleteGroup(id: number) {
    await api.delete(`/api/v1/route-groups/${id}`)
    await fetchGroups()
  }

  async function fetchRoutes(params?: { group_id?: number | null }) {
    routesLoading.value = true
    try {
      const data = await api.get<RouteRecord[]>('/api/v1/routes', params as Record<string, unknown>)
      routes.value = data
    } catch (err: unknown) {
      const msg = err instanceof Error ? err.message : '获取路由列表失败'
      message.error(msg)
    } finally {
      routesLoading.value = false
    }
  }

  async function assignRouteToGroup(routeId: number, groupId: number | null) {
    await api.put(`/api/v1/routes/${routeId}/group`, { group_id: groupId })
  }

  async function batchAssignRoutes(groupId: number, routeIds: number[]) {
    await api.put(`/api/v1/route-groups/${groupId}/routes`, { route_ids: routeIds })
    // 刻意获取全量路由（无过滤参数），因为 routeTree 需要完整数据构建树
    await Promise.all([fetchGroups(), fetchRoutes()])
  }

  async function syncRoutes() {
    await api.post('/api/v1/routes/sync')
    await Promise.all([fetchGroups(), fetchRoutes()])
  }

  // 按首段资源名分组，避免同名叶节点与目录共存导致 UI 混乱
  const routeTree = computed(() => {
    const root: RouteTreeNode[] = []
    const nodeMap = new Map<string, RouteTreeNode>()

    function getOrCreateDir(parent: RouteTreeNode[], pathKey: string, title: string) {
      let node = nodeMap.get(pathKey)
      if (!node) {
        node = { key: pathKey, title, children: [] }
        nodeMap.set(pathKey, node)
        parent.push(node)
      }
      return node
    }

    for (const route of routes.value) {
      const relative = route.path.replace(/^\/api\/v1\//, '')
      const segments = relative.split('/').filter(Boolean)
      if (segments.length === 0) continue

      const firstSeg = segments[0]!
      const dirNode = getOrCreateDir(root, '/' + firstSeg, firstSeg)

      if (segments.length === 1) {
        dirNode.children!.push({
          key: `route:${route.id}`,
          title: firstSeg,
          isLeaf: true,
          routeId: route.id,
          method: route.method,
          fullPath: route.path,
        })
      } else {
        let parentChildren = dirNode.children!
        let pathSoFar = '/' + firstSeg

        for (let i = 1; i < segments.length; i++) {
          const seg = segments[i]!
          pathSoFar += '/' + seg
          const isLast = i === segments.length - 1

          if (isLast) {
            parentChildren.push({
              key: `route:${route.id}`,
              title: seg,
              isLeaf: true,
              routeId: route.id,
              method: route.method,
              fullPath: route.path,
            })
          } else {
            const node = getOrCreateDir(parentChildren, pathSoFar, seg)
            parentChildren = node.children!
          }
        }
      }
    }

    return root
  })

  const checkedRouteKeys = computed(() => {
    if (typeof selectedGroupId.value !== 'number') return []
    return routes.value
      .filter((r) => r.group_id === selectedGroupId.value)
      .map((r) => `route:${r.id}`)
  })

  return {
    groups,
    routes,
    loading,
    routesLoading,
    selectedGroupId,
    fetchGroups,
    createGroup,
    updateGroup,
    deleteGroup,
    fetchRoutes,
    assignRouteToGroup,
    batchAssignRoutes,
    syncRoutes,
    routeTree,
    checkedRouteKeys,
  }
})
