// 侧边栏相关组件覆盖机制，优先级：
// 1) pagetype 视图下的 panel 组件（entity 专属）
//    - @apps/*/frontend/src/views/pagetype/<entity>/form/panel/<Comp>.vue
//    - /src/views/pagetype/<entity>/form/panel/<Comp>.vue
// 2) 核心路径的 panel 组件（源路径级覆盖）
//    - @apps/*/frontend/src/core/pagetype/form/panel/<Comp>.vue
//    - /src/core/pagetype/form/panel/<Comp>.vue
// 组件名 <Comp>：FormPanel.vue / ImageSection.vue / AttachmentSection.vue / TagSection.vue

declare const __APPS_ORDER__: string[]

type AsyncComponentLoader = () => Promise<any>

// 核心路径扫描
const globCoreApps = import.meta.glob('@apps/*/frontend/src/core/**/**.vue')
const globCoreLocal = import.meta.glob('/src/core/**/**.vue')
// pagetype 视图下的 panel 扫描
const globViewApps = import.meta.glob('@apps/*/frontend/src/views/pagetype/**/form/panel/**.vue')
const globViewLocal = import.meta.glob('/src/views/pagetype/**/form/panel/**.vue')

type Entry = {
  loader: AsyncComponentLoader
  appName: string
  fullPath: string
  key?: string // 核心源路径键（相对 src）
  entity?: string // 视图下的 entity
  compName: string // 组件名（文件名）
}

function appsOrder(): string[] {
  return Array.isArray(__APPS_ORDER__) && __APPS_ORDER__.length > 0 ? __APPS_ORDER__ : ['jingrow']
}

function rankByAppsOrder(appName: string): number {
  const order = appsOrder()
  const idx = order.indexOf(appName)
  return idx >= 0 ? idx : -1
}

function extractAppName(p: string): string {
  const s = p.replace(/\\/g, '/').replace(/^\/@fs\//, '/')
  if (s.startsWith('/src/')) return 'jingrow'
  const reApps1 = /(?:^|\/)apps\/([^/]+)\/frontend\//
  const reApps2 = /(?:^|\/)@apps\/([^/]+)\/frontend\//
  const m1 = s.match(reApps1)
  if (m1 && m1[1]) return m1[1]
  const m2 = s.match(reApps2)
  if (m2 && m2[1]) return m2[1]
  return 'jingrow'
}

function toKey(p: string): string | null {
  const s = p.replace(/\\/g, '/').replace(/^\/@fs\//, '/')
  const idx = s.indexOf('/src/')
  if (idx >= 0) return s.substring(idx + '/src/'.length)
  return null
}

function parseCompName(p: string): string {
  const s = p.replace(/\\/g, '/')
  const parts = s.split('/')
  const last = parts[parts.length - 1] || ''
  return last
}

function parseEntityFromViewPath(p: string): string | null {
  const s = p.replace(/\\/g, '/')
  const parts = s.split('/')
  const idx = parts.indexOf('pagetype')
  if (idx >= 0 && idx + 1 < parts.length) return parts[idx + 1]
  return null
}

const allEntries: Entry[] = []

// 核心路径 entries
for (const [p, loader] of Object.entries(globCoreApps)) {
  const key = toKey(p)
  if (!key) continue
  allEntries.push({ loader: loader as AsyncComponentLoader, appName: extractAppName(p), fullPath: p, key, compName: parseCompName(p) })
}
for (const [p, loader] of Object.entries(globCoreLocal)) {
  const key = toKey(p)
  if (!key) continue
  allEntries.push({ loader: loader as AsyncComponentLoader, appName: extractAppName(p), fullPath: p, key, compName: parseCompName(p) })
}

// 视图路径 entries（带 entity）
for (const [p, loader] of Object.entries(globViewApps)) {
  const entity = parseEntityFromViewPath(p)
  if (!entity) continue
  allEntries.push({ loader: loader as AsyncComponentLoader, appName: extractAppName(p), fullPath: p, entity, compName: parseCompName(p) })
}
for (const [p, loader] of Object.entries(globViewLocal)) {
  const entity = parseEntityFromViewPath(p)
  if (!entity) continue
  allEntries.push({ loader: loader as AsyncComponentLoader, appName: extractAppName(p), fullPath: p, entity, compName: parseCompName(p) })
}

// 索引：
// - viewIndex[(entity, compName)] -> entries（pagetype 覆盖）
// - coreIndex[(compName)] -> entries（核心路径覆盖）
const viewIndex: Record<string, Entry[]> = {}
const coreIndex: Record<string, Entry[]> = {}

for (const e of allEntries) {
  if (e.entity) {
    const key = `${e.entity}:${e.compName}`
    if (!viewIndex[key]) viewIndex[key] = []
    viewIndex[key].push(e)
  } else if (e.key) {
    const key = e.compName
    if (!coreIndex[key]) coreIndex[key] = []
    coreIndex[key].push(e)
  }
}

function sortEntries(list: Entry[]) {
  list.sort((a, b) => {
    const ra = rankByAppsOrder(a.appName)
    const rb = rankByAppsOrder(b.appName)
    if (ra !== rb) return rb - ra
    const aIsExternal = a.fullPath.includes('/apps/') || a.fullPath.includes('@apps/')
    const bIsExternal = b.fullPath.includes('/apps/') || b.fullPath.includes('@apps/')
    if (aIsExternal !== bIsExternal) return aIsExternal ? -1 : 1
    if (a.fullPath.length !== b.fullPath.length) return a.fullPath.length - b.fullPath.length
    return a.fullPath.localeCompare(b.fullPath)
  })
}

for (const k of Object.keys(viewIndex)) sortEntries(viewIndex[k])
for (const k of Object.keys(coreIndex)) sortEntries(coreIndex[k])

// 解析侧栏面板组件：优先 entity 下的视图 panel，其次核心路径 panel
export async function resolveSidebarPanel(entity: string, compName: string): Promise<any | null> {
  const entityKey = String(entity).toLowerCase().replace(/[-\s]/g, '_')
  const name = compName.endsWith('.vue') ? compName : `${compName}.vue`
  let bucket = viewIndex[`${entityKey}:${name}`]
  if ((!bucket || bucket.length === 0)) {
    bucket = coreIndex[name]
  }
  if (!bucket || bucket.length === 0) return null
  try {
    const mod = await bucket[0].loader()
    return mod?.default ?? mod
  } catch {
    return null
  }
}


