import { createRouter, createWebHistory, type RouteRecordRaw } from 'vue-router'
import { ElMessage } from 'element-plus'
import { useAuthStore } from '@/stores/auth'

const routes: RouteRecordRaw[] = [
  {
    path: '/login',
    name: 'login',
    component: () => import('@/views/LoginView.vue'),
    meta: { layout: 'blank', public: true, title: '登录' }
  },
  {
    path: '/status',
    name: 'status',
    component: () => import('@/views/ServiceStatusView.vue'),
    meta: { layout: 'blank', public: true, title: '服务状态' }
  },
  {
    // 部署配置向导：首次部署强制完成平台选型（导航方式 / 模块 / 功能）。需登录，但不属于 admin/monitor scope。
    path: '/wizard',
    name: 'wizard',
    component: () => import('@/views/WizardView.vue'),
    meta: { layout: 'blank', title: '配置向导' }
  },
  {
    path: '/admin',
    component: () => import('@/layouts/AppShell.vue'),
    meta: { scope: 'Platform' },
    redirect: '/admin/dashboard',
    children: [
      { path: 'dashboard', name: 'admin-dashboard', component: () => import('@/views/admin/DashboardView.vue'), meta: { title: '总览' } },
      { path: 'map-monitor', name: 'admin-map-monitor', component: () => import('@/views/admin/MapMonitorView.vue'), meta: { title: '地图监控' } },
      { path: 'tasks', name: 'admin-tasks', component: () => import('@/views/admin/TaskManagementView.vue'), meta: { title: '任务管理' } },
      { path: 'alarms', name: 'admin-alarms', component: () => import('@/views/admin/AlarmManagementView.vue'), meta: { title: '报警管理' } },
      { path: 'maps', name: 'admin-maps', component: () => import('@/views/admin/MapManagementView.vue'), meta: { title: '地图管理' } },
      { path: 'map-editor', name: 'admin-map-editor', component: () => import('@/views/admin/MapEditorView.vue'), meta: { title: '地图编辑' } },
      { path: 'tracks', name: 'admin-tracks', component: () => import('@/views/admin/TrackTableView.vue'), meta: { title: '场景管理' } },
      { path: 'cars', name: 'admin-cars', component: () => import('@/views/admin/CarPanelView.vue'), meta: { title: '车辆管理' } },
      { path: 'processes', name: 'admin-processes', component: () => import('@/views/admin/ProcessPanelView.vue'), meta: { title: '进程管理' } },
      { path: 'scripts', name: 'admin-scripts', component: () => import('@/views/admin/ScriptPanelView.vue'), meta: { title: '脚本管理' } },
      { path: 'task-templates', name: 'admin-task-templates', component: () => import('@/views/admin/TaskTemplateView.vue'), meta: { title: '任务编排' } },
      { path: 'simple-fields', name: 'admin-simple-fields', component: () => import('@/views/admin/SimpleFieldManagementView.vue'), meta: { title: '字段管理' } },
      { path: 'project-properties', name: 'admin-project-properties', component: () => import('@/views/admin/ProjectPropertiesView.vue'), meta: { title: '项目属性' } },
      // ── 平台配置中心：聚合页 + 独立业务页（page key = route.name，对齐后端 PageCatalog）。 ──
      { path: 'config/strategy', name: 'admin-config-strategy', component: () => import('@/views/admin/config/StrategyConfigView.vue'), meta: { title: '调度策略' } },
      { path: 'config/vehicle-hub', name: 'admin-vehicle-hub', component: () => import('@/views/shared/VehicleHubView.vue'), meta: { title: '车辆运维' } },
      { path: 'config/facility', name: 'admin-config-facility', component: () => import('@/views/admin/config/FacilityConfigView.vue'), meta: { title: '设备接入' } },
      { path: 'config/warehouse', name: 'admin-config-warehouse', component: () => import('@/views/admin/WarehouseManagementView.vue'), meta: { title: '仓储管理' } },
      { path: 'config/business', name: 'admin-config-business', component: () => import('@/views/admin/config/BusinessConfigView.vue'), meta: { title: '业务与集成' } },
      { path: 'config/ops-center', name: 'admin-config-ops-center', component: () => import('@/views/admin/config/OpsCenterView.vue'), meta: { title: '运维与回放' } },
      { path: 'config/system-center', name: 'admin-config-system-center', component: () => import('@/views/admin/config/SystemCenterView.vue'), meta: { title: '系统与权限' } },

      // ── 旧路径深链接兼容：redirect 到聚合页对应 tab（无 name → 不计入受权限管理的页面）。 ──
      { path: 'playback', redirect: { path: '/admin/config/ops-center', query: { tab: 'playback' } } },
      { path: 'vehicle-hub', redirect: '/admin/config/vehicle-hub' },
      { path: 'config/vehicle', redirect: { path: '/admin/config/vehicle-hub', query: { tab: 'ota' } } },
      { path: 'config/fleet', redirect: { path: '/admin/config/vehicle-hub', query: { tab: 'ota' } } },
      { path: 'config/routing', redirect: { path: '/admin/config/strategy', query: { tab: 'routing' } } },
      { path: 'config/task', redirect: { path: '/admin/config/strategy', query: { tab: 'task' } } },
      { path: 'config/traffic', redirect: { path: '/admin/config/strategy', query: { tab: 'traffic' } } },
      { path: 'config/charge', redirect: { path: '/admin/config/strategy', query: { tab: 'charge' } } },
      { path: 'config/device', redirect: '/admin/config/facility' },
      { path: 'config/location', redirect: '/admin/config/warehouse' },
      { path: 'config/integrations', redirect: { path: '/admin/config/business', query: { tab: 'integrations' } } },
      { path: 'config/scenario', redirect: { path: '/admin/config/business', query: { tab: 'scenario' } } },
      { path: 'config/widget', redirect: { path: '/admin/config/business', query: { tab: 'widget' } } },
      { path: 'config/ops', redirect: { path: '/admin/config/ops-center', query: { tab: 'ops' } } },
      { path: 'config/logs', redirect: { path: '/admin/config/ops-center', query: { tab: 'logs' } } },
      { path: 'config/map-monitor', redirect: { path: '/admin/config/ops-center', query: { tab: 'map-monitor' } } },
      { path: 'config/system', redirect: { path: '/admin/config/system-center', query: { tab: 'system' } } },
      { path: 'config/auth', redirect: { path: '/admin/config/system-center', query: { tab: 'auth' } } }
    ]
  },
  {
    path: '/monitor',
    component: () => import('@/layouts/AppShell.vue'),
    meta: { scope: 'RCSMonitor' },
    redirect: '/monitor/map',
    children: [
      { path: 'dashboard', name: 'monitor-dashboard', component: () => import('@/views/monitor/MonitorDashboardView.vue'), meta: { title: '运营总览' } },
      { path: 'vehicle-hub', name: 'monitor-vehicle-hub', component: () => import('@/views/shared/VehicleHubView.vue'), meta: { title: '车辆运维' } },
      { path: 'map', name: 'monitor-map', component: () => import('@/views/monitor/MonitorMapView.vue'), meta: { title: '地图监控' } },
      { path: 'ops', name: 'monitor-ops', component: () => import('@/views/monitor/OpsActionPanelView.vue'), meta: { title: '运维操作' } },
      { path: 'notes', name: 'monitor-notes', component: () => import('@/views/monitor/AnnotationView.vue'), meta: { title: '运营备注' } }
    ]
  },
  { path: '/', redirect: '/login' },
  { path: '/:pathMatch(.*)*', redirect: '/login' }
]

/**
 * RBAC 页面权限：route.name 即「权限页面 Key」（与后端 PageCatalog / EffectivePermissions.allowedPages 对齐）。
 * 这里从路由表派生出各 scope 的有序页面列表，供守卫做权限校验与「跳到首个可访问页面」的回退。
 */
function childrenPages(parentPath: string): Array<{ name: string; path: string }> {
  const parent = routes.find((r) => r.path === parentPath)
  return ((parent?.children ?? []) as RouteRecordRaw[])
    .filter((c) => typeof c.name === 'string')
    .map((c) => ({ name: String(c.name), path: `${parentPath}/${(c as { path: string }).path}` }))
}
const ADMIN_PAGES = childrenPages('/admin')
const MONITOR_PAGES = childrenPages('/monitor')
const MANAGED_PAGE_NAMES = new Set([...ADMIN_PAGES, ...MONITOR_PAGES].map((p) => p.name))

const router = createRouter({
  history: createWebHistory(),
  routes
})

router.beforeEach(async (to) => {
  const auth = useAuthStore()
  if (to.meta.public) return true
  if (!auth.isAuthed) {
    return { path: '/login', query: { redirect: to.fullPath } }
  }

  // 关键守卫：localStorage 里只要有 token 字符串 isAuthed 就为 true，但服务端可能已经
  // 不认这个 token（最常见：Platform.Server 用占位 Jwt:Secret 启动，每次重启 secret 重生 →
  // 历史 token 全部失效）。如果进入受保护路由后页面恰好没立刻发 API，旧 401 拦截路径不会
  // 触发，用户就能「看到」框架页 → 看起来是「跳过了登录页」。
  //
  // 解决：本浏览器会话内首次进入受保护路由前 await 一次 validate（GET /api/auth/me），
  // 由后端 [Authorize] 判定 token 是否仍有效。失败 → store 已清空、跳 /login 并带 redirect。
  if (!auth.validated) {
    try {
      await auth.validate()
    } catch {
      return { path: '/login', query: { redirect: to.fullPath } }
    }
  }

  // 部署配置向导：首次部署（deployment.Configured=false）时，强制先完成平台选型再进入业务页。
  // 已在 /wizard 则放行，避免自跳死循环；保存成功后 store.markWizardDone() 解除拦截。
  if (auth.needsWizard && to.name !== 'wizard') {
    return { name: 'wizard' }
  }

  // 会话 45 AR-6：switchScope 改为后端发起 ——
  // 必须 await 完成后再放行，否则页面用旧 scope 的 perms 渲染一帧后才被纠正。
  // 失败（如 ops 账号尝试切 Platform 被 403）则维持原 scope，路由仍放行让用户看到 readonly UI。
  const needScope: 'Platform' | 'RCSMonitor' | null =
    to.path.startsWith('/admin')
      ? 'Platform'
      : to.path.startsWith('/monitor') ? 'RCSMonitor'
        : null
  if (needScope && auth.scope !== needScope) {
    try {
      await auth.switchScope(needScope)
    } catch (_) {
      // 偶发失败（网络/超时）重试一次：避免带着「另一个域」的 effectivePermissions 渲染当前页，
      // 否则配置页会被 PermissionGuard 误判为隐藏 → 整页空白（刷新后重新 switch 才恢复）。
      try { await auth.switchScope(needScope) } catch (_2) { /* 仍失败：维持原 scope，UI 多为 readonly */ }
    }
  }

  // RBAC 页面级权限：scope 已切换到目标域，allowedPages 已刷新。
  // 若目标页面不在当前账号的可访问页面集合内，跳到该 scope 下首个可访问页面（菜单顺序）。
  const name = typeof to.name === 'string' ? to.name : ''
  const pageKey = typeof to.meta.pageKey === 'string' ? to.meta.pageKey : name
  if (pageKey && MANAGED_PAGE_NAMES.has(pageKey) && !auth.hasPage(pageKey)) {
    const list = auth.scope === 'RCSMonitor' ? MONITOR_PAGES : ADMIN_PAGES
    const fallback = list.find((p) => auth.hasPage(p.name))?.path
    if (fallback && fallback !== to.path) {
      ElMessage.warning('无权访问该页面，已跳转到可访问页面')
      return fallback
    }
    if (!fallback) {
      ElMessage.error('当前账号在该区域没有任何可访问页面，请联系管理员分配权限')
      return { path: '/status' }
    }
  }
  return true
})

router.afterEach((to) => {
  const base = '迷毂'
  document.title = to.meta.title ? `${to.meta.title} · ${base}` : base
})

// 懒加载 chunk 失败自愈：重新部署后产物 hash 变化、或网络抖动会让动态 import() 失败，
// 表现为点击导航后白屏、刷新才好。这里捕获该类错误并整页重载到目标路由，
// 让浏览器重新拉取最新的 index.html 与对应 chunk 引用。
router.onError((error, to) => {
  const m = (error as Error)?.message ?? ''
  if (/dynamically imported module|Loading (chunk|CSS chunk)|module script failed|Failed to fetch/i.test(m)) {
    if (to?.fullPath) window.location.assign(to.fullPath)
    else window.location.reload()
  }
})

export default router
