// 基于约定路径自动解析 pagetype 覆盖组件
// 详情页：/src/views/pagetype/<pagetype>/<pagetype>.vue
// 详情页工具栏：/src/views/pagetype/<pagetype>/<pagetype>_toolbar.vue
// 列表页：/src/views/pagetype/<pagetype>/<pagetype>_list.vue
// 列表页工具栏：/src/views/pagetype/<pagetype>/<pagetype>_list_toolbar.vue
// 列表页过滤栏：/src/views/pagetype/<pagetype>/<pagetype>_list_filterbar.vue
// 列表页操作列：/src/views/pagetype/<pagetype>/<pagetype>_list_actions.vue

// 由 Vite define 注入，类型声明便于 TS
declare const __APPS_ORDER__: string[]

type AsyncComponentLoader = () => Promise<any>

// 扫描所有可能的覆盖组件（仅限 .vue）
// - 扫描所有 apps 下的前端视图：@apps/*/frontend/src/views/pagetype
// - 同时扫描当前应用 src 下的视图：/src/views/pagetype
// 说明：@apps 别名与 devServer.fs.allow 已在 vite.config.ts 放行
const globAllApps = import.meta.glob('@apps/*/frontend/src/views/pagetype/**/**.vue')
const globLocal = import.meta.glob('/src/views/pagetype/**/**.vue')

type SourceEntry = {
  loader: AsyncComponentLoader
  appName: string
  fullPath: string
}

const allPagetypeViews: Record<string, SourceEntry> = {}

function extractAppName(absPath: string): string {
  // 形如 @apps/<app>/frontend/src/...
  const parts = absPath.split('/')
  const idx = parts.indexOf('apps')
  if (idx >= 0 && idx + 1 < parts.length) {
    return parts[idx + 1]
  }
  // 本地 src 视为 jingrow（核心）
  return 'jingrow'
}

// 缓存应用顺序和排名，避免重复计算
const APP_ORDER: readonly string[] = Object.freeze(
  Array.isArray(__APPS_ORDER__) && __APPS_ORDER__.length > 0 ? __APPS_ORDER__ : ['jingrow']
)
const APP_RANK_CACHE = new Map<string, number>()

function getAppRank(appName: string): number {
  if (!APP_RANK_CACHE.has(appName)) {
    const idx = APP_ORDER.indexOf(appName)
    APP_RANK_CACHE.set(appName, idx >= 0 ? idx : -1)
  }
  return APP_RANK_CACHE.get(appName)!
}

for (const [p, loader] of Object.entries(globAllApps)) {
  const appName = extractAppName(p)
  allPagetypeViews[p] = { loader: loader as AsyncComponentLoader, appName, fullPath: p }
}
for (const [p, loader] of Object.entries(globLocal)) {
  const appName = extractAppName(p)
  allPagetypeViews[p] = { loader: loader as AsyncComponentLoader, appName, fullPath: p }
}

function sortByPriority(a: string, b: string): number {
  const ra = getAppRank(allPagetypeViews[a].appName)
  const rb = getAppRank(allPagetypeViews[b].appName)
  if (ra !== rb) return rb - ra
  if (a.length !== b.length) return a.length - b.length
  return a.localeCompare(b)
}

// 预索引：按 entity 分组，分别索引 detail、toolbar、list、listToolbar、filterbar、actions 候选，并在构建时一次性排序
type Indexed = { 
  detail: string[]
  toolbar: string[]
  list: string[]
  listToolbar: string[]
  filterbar: string[]
  actions: string[]
}
const indexedByEntity: Record<string, Indexed> = {}

function ensureIndexed(entity: string): Indexed {
  if (!indexedByEntity[entity]) {
    indexedByEntity[entity] = { detail: [], toolbar: [], list: [], listToolbar: [], filterbar: [], actions: [] }
  }
  return indexedByEntity[entity]
}

// 性能优化：使用正则表达式一次性提取路径信息，避免多次字符串扫描
const PAGETYPE_PATH_REGEX = /\/pagetype\/([^/]+)\/([^/]+)\.vue$/i

// 文件类型映射表（预编译，避免运行时字符串拼接）
function getBucketType(folderName: string, baseName: string): keyof Indexed | null {
  if (baseName === folderName) return 'detail'
  if (baseName === `${folderName}_toolbar`) return 'toolbar'
  if (baseName === `${folderName}_list`) return 'list'
  if (baseName === `${folderName}_list_toolbar`) return 'listToolbar'
  if (baseName === `${folderName}_list_filterbar`) return 'filterbar'
  if (baseName === `${folderName}_list_actions`) return 'actions'
  return null
}

// 构建索引（优化版：正则表达式 + 快速映射）
for (const file of Object.keys(allPagetypeViews)) {
  const match = file.match(PAGETYPE_PATH_REGEX)
  if (!match) continue
  
  const [, folderName, fileName] = match
  const baseName = fileName.replace(/\.vue$/i, '').toLowerCase()
  const folderNameLower = folderName.toLowerCase()
  const entity = folderNameLower
  const bucket = ensureIndexed(entity)
  
  const type = getBucketType(folderNameLower, baseName)
  if (type) {
    bucket[type].push(file)
  }
}

// 候选按优先级排序
Object.values(indexedByEntity).forEach(({ detail, toolbar, list, listToolbar, filterbar, actions }) => {
  detail.sort(sortByPriority)
  toolbar.sort(sortByPriority)
  list.sort(sortByPriority)
  listToolbar.sort(sortByPriority)
  filterbar.sort(sortByPriority)
  actions.sort(sortByPriority)
})

// 通用的解析函数（消除代码重复）
async function resolveOverride(
  pagetypeSlug: string,
  bucketType: keyof Indexed
): Promise<any | null> {
  if (!pagetypeSlug) return null
  const normalizedEntity = pagetypeSlug.toLowerCase().replace(/[-\s]+/g, '_')
  const bucket = indexedByEntity[normalizedEntity]
  if (!bucket || bucket[bucketType].length === 0) return null
  const pick = bucket[bucketType][0]
  try {
    const mod = await allPagetypeViews[pick].loader()
    return mod?.default ?? mod
  } catch {
    return null
  }
}

/**
 * 解析并返回指定 pagetype 的详情覆盖组件
 * @param pagetypeSlug 路由中的原始 pagetype（保持小写与下划线）
 */
export async function resolvePagetypeDetailOverride(pagetypeSlug: string): Promise<any | null> {
  return resolveOverride(pagetypeSlug, 'detail')
}

/**
 * 解析并返回指定 pagetype 的工具栏覆盖组件
 * 约定文件名：/src/views/pagetype/<name>/<name>_toolbar.vue
 */
export async function resolvePagetypeToolbarOverride(pagetypeSlug: string): Promise<any | null> {
  return resolveOverride(pagetypeSlug, 'toolbar')
}

/**
 * 解析并返回指定 pagetype 的列表页覆盖组件
 * 约定文件名：/src/views/pagetype/<name>/<name>_list.vue
 */
export async function resolvePagetypeListOverride(pagetypeSlug: string): Promise<any | null> {
  return resolveOverride(pagetypeSlug, 'list')
}

/**
 * 解析并返回指定 pagetype 的列表页过滤栏覆盖组件
 * 约定文件名：/src/views/pagetype/<name>/<name>_list_filterbar.vue
 */
export async function resolvePagetypeListFilterBarOverride(pagetypeSlug: string): Promise<any | null> {
  return resolveOverride(pagetypeSlug, 'filterbar')
}

/**
 * 解析并返回指定 pagetype 的列表页工具栏覆盖组件
 * 约定文件名：/src/views/pagetype/<name>/<name>_list_toolbar.vue
 */
export async function resolvePagetypeListToolbarOverride(pagetypeSlug: string): Promise<any | null> {
  return resolveOverride(pagetypeSlug, 'listToolbar')
}

/**
 * 解析并返回指定 pagetype 的列表页操作列覆盖组件
 * 约定文件名：/src/views/pagetype/<name>/<name>_list_actions.vue
 */
export async function resolvePagetypeListActionsOverride(pagetypeSlug: string): Promise<any | null> {
  return resolveOverride(pagetypeSlug, 'actions')
}
