export interface NavigationRouteLike {
  path: string
  meta?: Record<string, unknown>
}

export interface NavigationEntry {
  screenId: string
  path: string
  module: string
  section: string
  title: string
  order: number
  favoriteAllowed: boolean
  internalOnly: boolean
  permissions: readonly string[]
}

export interface NavigationSection {
  module: string
  entries: NavigationEntry[]
}

function toEntry(route: NavigationRouteLike): NavigationEntry | null {
  const meta = route.meta
  if (!meta || typeof meta.screenId !== 'string' || typeof meta.module !== 'string') return null
  if (meta.module === 'Home') return null
  if (route.path.includes(':')) return null
  return {
    screenId: meta.screenId,
    path: route.path,
    module: meta.module,
    section: typeof meta.section === 'string' ? meta.section : meta.module,
    title: typeof meta.title === 'string' ? meta.title : route.path,
    order: typeof meta.order === 'number' ? meta.order : 0,
    favoriteAllowed: meta.favoriteAllowed !== false,
    internalOnly: meta.internalOnly === true,
    permissions: Array.isArray(meta.permissions) && meta.permissions.every(permission => typeof permission === 'string')
      ? meta.permissions
      : []
  }
}

/** UI visibility hint only; the API remains the authorization authority. */
export function filterNavigationEntries(entries: readonly NavigationEntry[], grantedPermissions: ReadonlySet<string>): NavigationEntry[] {
  return entries.filter(entry => entry.permissions.every(permission => grantedPermissions.has(permission)))
}

/** router.getRoutes()의 flat route 목록에서 즐겨찾기/검색/사이드바가 공유하는 단일 카탈로그를 파생한다. */
export function buildNavigationEntries(routes: readonly NavigationRouteLike[]): NavigationEntry[] {
  const entries = routes.map(toEntry).filter((entry): entry is NavigationEntry => entry !== null)
  return entries.sort((a, b) => a.module.localeCompare(b.module) || a.order - b.order)
}

export function groupByModule(entries: readonly NavigationEntry[]): NavigationSection[] {
  const byModule = new Map<string, NavigationEntry[]>()
  for (const entry of entries) {
    const list = byModule.get(entry.module) ?? []
    list.push(entry)
    byModule.set(entry.module, list)
  }
  return [...byModule.entries()].map(([module, list]) => ({ module, entries: [...list].sort((a, b) => a.order - b.order) }))
}
