import { createRouter, createWebHistory } from "vue-router"
import type { RouteRecordRaw } from "vue-router"
import { nextTick } from "vue"
import { useAuthStore } from "@/stores/auth"
import { convertMenusToRoutes } from "@/utils/menu"
import "@/types/router"

// 基础路由（不需要动态加载的）
const baseRoutes: RouteRecordRaw[] = [
  {
    path: "/:tenantCode/login",
    name: "Login",
    component: () => import("@/views/auth/Login.vue"),
    meta: { requiresAuth: false },
  },
  {
    path: "/login",
    name: "LoginFallback",
    component: () => import("@/views/auth/Login.vue"),
    meta: { requiresAuth: false },
  },
  // ========== 公众端路由 ==========
  {
    path: "/p/login",
    name: "PublicLogin",
    component: () => import("@/views/public/Login.vue"),
    meta: { requiresAuth: false },
  },
  {
    path: "/p",
    component: () => import("@/layouts/PublicLayout.vue"),
    meta: { requiresAuth: false },
    children: [
      {
        path: "",
        name: "PublicMain",
        redirect: "/p/gallery",
      },
      {
        path: "gallery",
        name: "PublicGallery",
        component: () => import("@/views/public/Gallery.vue"),
        meta: { title: "作品广场" },
      },
      {
        path: "activities",
        name: "PublicActivities",
        component: () => import("@/views/public/Activities.vue"),
        meta: { title: "活动大厅" },
      },
      {
        path: "activities/:id",
        name: "PublicActivityDetail",
        component: () => import("@/views/public/ActivityDetail.vue"),
        meta: { title: "活动详情" },
      },
      {
        path: "mine",
        name: "PublicMine",
        component: () => import("@/views/public/mine/Index.vue"),
        meta: { title: "个人中心" },
      },
      {
        path: "mine/registrations",
        name: "PublicMyRegistrations",
        component: () => import("@/views/public/mine/Registrations.vue"),
        meta: { title: "我的报名" },
      },
      {
        path: "mine/favorites",
        name: "PublicMyFavorites",
        component: () => import("@/views/public/mine/Favorites.vue"),
        meta: { title: "我的收藏" },
      },
      {
        path: "mine/children",
        name: "PublicMyChildren",
        component: () => import("@/views/public/mine/Children.vue"),
        meta: { title: "子女账号" },
      },
      // ========== AI 绘本创作（嵌套路由） ==========
      {
        path: "create",
        name: "PublicCreateShell",
        component: () => import("@/views/public/create/Index.vue"),
        meta: { title: "绘本创作" },
        children: [
          {
            path: "",
            name: "PublicCreateWelcome",
            component: () => import("@/views/public/create/views/WelcomeView.vue"),
          },
          {
            path: "upload",
            name: "PublicCreateUpload",
            component: () => import("@/views/public/create/views/UploadView.vue"),
          },
          {
            path: "characters",
            name: "PublicCreateCharacters",
            component: () => import("@/views/public/create/views/CharactersView.vue"),
          },
          {
            path: "story",
            name: "PublicCreateStory",
            component: () => import("@/views/public/create/views/StoryInputView.vue"),
          },
          {
            path: "style",
            name: "PublicCreateStyle",
            component: () => import("@/views/public/create/views/StyleSelectView.vue"),
          },
          {
            path: "creating",
            name: "PublicCreateCreating",
            component: () => import("@/views/public/create/views/CreatingView.vue"),
          },
          {
            path: "preview/:workId?",
            name: "PublicCreatePreview",
            component: () => import("@/views/public/create/views/PreviewView.vue"),
          },
          {
            path: "edit-info/:workId",
            name: "PublicCreateEditInfo",
            component: () => import("@/views/public/create/views/EditInfoView.vue"),
          },
          {
            path: "save-success/:workId",
            name: "PublicCreateSaveSuccess",
            component: () => import("@/views/public/create/views/SaveSuccessView.vue"),
          },
          {
            path: "dubbing/:workId",
            name: "PublicCreateDubbing",
            component: () => import("@/views/public/create/views/DubbingView.vue"),
          },
          {
            path: "read/:workId",
            name: "PublicCreateRead",
            component: () => import("@/views/public/create/views/BookReaderView.vue"),
            meta: { noAuth: true },
          },
        ],
      },
      {
        path: "works",
        name: "PublicWorksList",
        component: () => import("@/views/public/works/Index.vue"),
        meta: { title: "我的作品库" },
      },
      {
        path: "works/:id",
        name: "PublicWorkDetail",
        component: () => import("@/views/public/works/Detail.vue"),
        meta: { title: "作品详情" },
      },
    ],
  },
  // ========== 管理端路由 ==========
  {
    path: "/:tenantCode",
    name: "Main",
    component: () => import("@/layouts/BasicLayout.vue"),
    // 不设置固定redirect，由路由守卫根据用户菜单动态跳转到第一个可见菜单
    meta: {},
    children: [
      // 创建活动路由（不需要在菜单中显示）
      {
        path: "contests/create",
        name: "ContestsCreate",
        component: () => import("@/views/contests/Create.vue"),
        meta: {
          title: "创建活动",
          requiresAuth: true,
          permissions: ["contest:create"],
        },
      },
      // 超管活动详情路由
      {
        path: "contests/:id/overview",
        name: "SuperContestOverview",
        component: () => import("@/views/contests/SuperDetail.vue"),
        meta: {
          title: "活动详情",
          requiresAuth: true,
        },
      },
      // 活动详情路由（不需要在菜单中显示）
      {
        path: "contests/:id",
        name: "ContestsDetail",
        component: () => import("@/views/contests/Detail.vue"),
        meta: {
          title: "活动详情",
          requiresAuth: true,
          permissions: ["contest:read", "activity:read"],
        },
      },
      // 编辑活动路由（不需要在菜单中显示）
      {
        path: "contests/:id/edit",
        name: "ContestsEdit",
        component: () => import("@/views/contests/Create.vue"),
        meta: {
          title: "编辑活动",
          requiresAuth: true,
          permissions: ["contest:update"],
        },
      },
      // 活动评委管理路由（不需要在菜单中显示）
      {
        path: "contests/:id/judges",
        name: "ContestsJudges",
        component: () => import("@/views/contests/judges/Index.vue"),
        meta: {
          title: "评委管理",
          requiresAuth: true,
          permissions: ["contest:read"],
        },
      },
      // 个人参与报名路由
      {
        path: "contests/:id/register/individual",
        name: "ContestsRegisterIndividual",
        component: () => import("@/views/contests/RegisterIndividual.vue"),
        meta: {
          title: "活动报名（个人参与）",
          requiresAuth: true,
        },
      },
      // 团队参与报名路由
      {
        path: "contests/:id/register/team",
        name: "ContestsRegisterTeam",
        component: () => import("@/views/contests/RegisterTeam.vue"),
        meta: {
          title: "活动报名（团队参与）",
          requiresAuth: true,
        },
      },
      // 报名管理列表路由
      {
        path: "contests/registrations",
        name: "ContestsRegistrations",
        component: () => import("@/views/contests/registrations/Index.vue"),
        meta: {
          title: "报名管理",
          requiresAuth: true,
          permissions: ["registration:read", "contest:read"],
        },
      },
      // 报名记录路由
      {
        path: "contests/registrations/:id/records",
        name: "RegistrationRecords",
        component: () => import("@/views/contests/registrations/Records.vue"),
        meta: {
          title: "报名记录",
          requiresAuth: true,
          permissions: ["registration:read", "contest:read"],
        },
      },
      // 评委评审详情路由（从评审任务列表进入）
      {
        path: "activities/review/:id",
        name: "ActivitiesReviewDetail",
        component: () => import("@/views/activities/ReviewDetail.vue"),
        meta: {
          title: "评审工作台",
          requiresAuth: true,
          permissions: ["review:score"],
        },
      },
      // 评审进度详情路由
      {
        path: "contests/reviews/:id/progress",
        name: "ReviewProgressDetail",
        component: () => import("@/views/contests/reviews/ProgressDetail.vue"),
        meta: {
          title: "评审进度详情",
          requiresAuth: true,
        },
      },
      // 成果发布详情路由
      {
        path: "contests/results/:id",
        name: "ContestsResultsDetail",
        component: () => import("@/views/contests/results/Detail.vue"),
        meta: {
          title: "成果发布详情",
          requiresAuth: true,
        },
      },
      // 参赛作品详情列表路由
      {
        path: "contests/works/:id/list",
        name: "WorksDetail",
        component: () => import("@/views/contests/works/WorksDetail.vue"),
        meta: {
          title: "参赛作品详情",
          requiresAuth: true,
          permissions: ["contest:work:read"],
        },
      },
      // 作业提交记录路由
      {
        path: "homework/submissions",
        name: "HomeworkSubmissions",
        component: () => import("@/views/homework/Submissions.vue"),
        meta: {
          title: "作业提交记录",
          requiresAuth: true,
          permissions: ["homework:read"],
        },
      },
      // 学生作业详情路由
      {
        path: "homework/detail/:id",
        name: "HomeworkDetail",
        component: () => import("@/views/homework/StudentDetail.vue"),
        meta: {
          title: "作业详情",
          requiresAuth: true,
          permissions: ["homework:read"],
        },
      },
      // 教师我的指导路由
      {
        path: "student-activities/guidance",
        name: "TeacherGuidance",
        component: () => import("@/views/contests/Guidance.vue"),
        meta: {
          title: "我的指导",
          requiresAuth: true,
          permissions: ["activity:read"],
        },
      },
      // 评委评审详情页
      {
        path: "activities/review/:id",
        name: "ReviewDetail",
        component: () => import("@/views/activities/ReviewDetail.vue"),
        meta: {
          title: "作品评审",
          requiresAuth: true,
        },
      },
      // 预设评语页面
      {
        path: "activities/preset-comments",
        name: "PresetComments",
        component: () => import("@/views/activities/PresetComments.vue"),
        meta: {
          title: "预设评语",
          requiresAuth: true,
        },
      },
      // 动态路由将在这里添加
    ],
  },
  {
    path: "/403",
    name: "Forbidden",
    component: () => import("@/views/error/403.vue"),
    meta: { requiresAuth: false },
  },
  {
    path: "/:pathMatch(.*)*",
    name: "NotFound",
    component: () => import("@/views/error/404.vue"),
  },
]

const router = createRouter({
  history: createWebHistory(import.meta.env.BASE_URL),
  routes: baseRoutes,
})

// 标记是否已经添加了动态路由
let dynamicRoutesAdded = false
// 保存已添加的路由名称，用于清理
let addedRouteNames: string[] = []
// 保存上次的菜单数据，用于检测变化
let lastMenusHash: string = ""

/**
 * 重置动态路由标记（用于登出或切换用户时）
 */
export function resetDynamicRoutes(): void {
  dynamicRoutesAdded = false
  addedRouteNames = []
  lastMenusHash = ""
}

/**
 * 添加动态路由
 * @returns Promise，当路由添加完成并生效后 resolve
 */
export async function addDynamicRoutes(): Promise<void> {
  const authStore = useAuthStore()
  if (!authStore.menus || authStore.menus.length === 0) {
    // 如果没有菜单，重置标记
    if (dynamicRoutesAdded) {
      resetDynamicRoutes()
    }
    return
  }

  // 计算菜单数据的哈希值，用于检测变化
  const menusHash = JSON.stringify(
    authStore.menus.map((m) => ({ id: m.id, path: m.path }))
  )

  // 如果菜单数据没有变化且已经添加过路由，直接返回
  if (dynamicRoutesAdded && menusHash === lastMenusHash) {
    return
  }

  // 如果已经添加过路由，先移除旧路由
  if (dynamicRoutesAdded && addedRouteNames.length > 0) {
    addedRouteNames.forEach((routeName) => {
      if (router.hasRoute(routeName)) {
        router.removeRoute(routeName)
      }
    })
    addedRouteNames = []
  }

  // 将菜单转换为路由
  const dynamicRoutes = convertMenusToRoutes(authStore.menus)

  if (dynamicRoutes.length === 0) {
    return
  }

  // 添加动态路由到根路由下
  dynamicRoutes.forEach((route) => {
    router.addRoute("Main", route)
    if (route.name) {
      addedRouteNames.push(route.name as string)
    }
  })

  dynamicRoutesAdded = true
  lastMenusHash = menusHash

  // 等待多个 tick，确保路由已完全注册
  await nextTick()
  await nextTick()
  await nextTick()

  // 额外等待一小段时间，确保路由系统完全更新
  await new Promise((resolve) => setTimeout(resolve, 50))
}

/**
 * 从路径中提取租户编码
 */
function extractTenantCodeFromPath(path: string): string | null {
  const match = path.match(/^\/([^/]+)/)
  return match ? match[1] : null
}

/**
 * 构建带租户编码的路径
 */
function buildPathWithTenantCode(tenantCode: string, path: string): string {
  // 如果路径已经包含租户编码，直接返回
  if (path.startsWith(`/${tenantCode}/`)) {
    return path
  }
  // 移除开头的斜杠（如果有）
  const cleanPath = path.startsWith("/") ? path.slice(1) : path
  // 如果路径是根路径，返回租户编码根路径（路由守卫会处理跳转到第一个菜单）
  if (cleanPath === "" || cleanPath === tenantCode) {
    return `/${tenantCode}`
  }
  return `/${tenantCode}/${cleanPath}`
}

router.beforeEach(async (to, _from, next) => {
  // 公众端路由不走管理端认证逻辑，直接放行
  if (to.path.startsWith("/p/") || to.path === "/p") {
    next()
    return
  }

  // 根路径：检查公众端登录状态，已登录则跳转活动大厅，未登录则跳转公众端登录页
  if (to.path === "/") {
    if (localStorage.getItem("public_token")) {
      next({ path: "/p/activities", replace: true })
    } else {
      next({ path: "/p/login", replace: true })
    }
    return
  }

  const authStore = useAuthStore()
  const tenantCodeFromUrl = extractTenantCodeFromPath(to.path)

  // ─── 1. 已登录但无用户信息：首次加载，尝试获取 ───
  if (authStore.token && !authStore.user) {
    await handleFirstLoad(to, authStore, tenantCodeFromUrl, next)
    return
  }

  // ─── 2. 无 Token 但需要认证：跳转登录 ───
  if (!authStore.token && to.meta.requiresAuth !== false) {
    redirectToLogin(to, tenantCodeFromUrl, next)
    return
  }

  // ─── 3. 已登录：检查租户编码一致性 ───
  if (authStore.isAuthenticated && authStore.user) {
    const corrected = checkTenantCodeConsistency(authStore, tenantCodeFromUrl, to)
    if (corrected) {
      next({ path: corrected, query: to.query, replace: true })
      return
    }
  }

  // ─── 4. 已登录且有菜单：添加动态路由 ───
  if (authStore.isAuthenticated && authStore.menus.length > 0) {
    const wasAdded = dynamicRoutesAdded
    await addDynamicRoutes()

    // 首次添加路由后需要重新导航
    if (!wasAdded && dynamicRoutesAdded) {
      await handleRoutesFirstAdded(to, authStore, tenantCodeFromUrl, next)
      return
    }
  }

  // ─── 5. 路由已加载：检查是否需要重定向到第一个菜单 ───
  if (authStore.isAuthenticated && dynamicRoutesAdded && authStore.menus.length > 0) {
    const isMainRoute = to.name === "Main" ||
      (to.matched.length === 1 && to.matched[0].name === "Main")
    const resolved = router.resolve(to.fullPath)

    if ((resolved.name === "NotFound" || isMainRoute) &&
        to.name !== "Login" && to.name !== "LoginFallback") {
      const firstPath = findFirstMenuPath(authStore.menus)
      const tc = tenantCodeFromUrl || authStore.user?.tenantCode
      if (firstPath && tc) {
        next({ path: `/${tc}/${firstPath}`, replace: true })
        return
      }
    }
  }

  // ─── 6. 需要认证的路由：二次检查 token 和用户信息 ───
  if (to.meta.requiresAuth !== false) {
    if (!authStore.token || !authStore.user) {
      redirectToLogin(to, tenantCodeFromUrl, next)
      return
    }
  }

  // ─── 7. 已登录访问登录页：重定向到首页 ───
  if ((to.name === "Login" || to.name === "LoginFallback") && authStore.isAuthenticated) {
    if (!dynamicRoutesAdded && authStore.menus.length > 0) {
      await addDynamicRoutes()
    }
    const userTenantCode = authStore.user?.tenantCode || "default"
    next({ path: `/${userTenantCode}` })
    return
  }

  // ─── 8. LoginFallback 无租户编码时尝试补全 ───
  if (to.name === "LoginFallback" && !tenantCodeFromUrl) {
    if (authStore.isAuthenticated && authStore.user?.tenantCode) {
      next({ path: `/${authStore.user.tenantCode}/login`, replace: true })
      return
    }
    next()
    return
  }

  // ─── 9. 检查角色和权限 ───
  if (to.meta.roles?.length && !authStore.hasAnyRole(to.meta.roles)) {
    next({ name: "Forbidden" })
    return
  }
  if (to.meta.permissions?.length && !authStore.hasAnyPermission(to.meta.permissions)) {
    next({ name: "Forbidden" })
    return
  }

  next()
})

// ==================== 路由守卫辅助函数 ====================

/**
 * 从菜单树中找到第一个有效菜单路径
 */
function findFirstMenuPath(menus: any[]): string | null {
  for (const menu of menus) {
    if (menu.path && menu.component) {
      return menu.path.startsWith("/") ? menu.path.slice(1) : menu.path
    }
    if (menu.children?.length) {
      const childPath = findFirstMenuPath(menu.children)
      if (childPath) return childPath
    }
  }
  return null
}

/**
 * 跳转到登录页
 */
function redirectToLogin(to: any, tenantCode: string | null, next: any) {
  if (tenantCode) {
    next({ path: `/${tenantCode}/login`, query: { redirect: to.fullPath } })
  } else {
    next({ name: "LoginFallback", query: { redirect: to.fullPath } })
  }
}

/**
 * 检查租户编码一致性，返回修正后的路径（需要重定向时）或 null
 */
function checkTenantCodeConsistency(
  authStore: ReturnType<typeof useAuthStore>,
  tenantCodeFromUrl: string | null,
  to: any,
): string | null {
  const userTenantCode = authStore.user?.tenantCode
  if (!userTenantCode) return null

  // URL 中的租户编码与用户信息不一致
  if (tenantCodeFromUrl && tenantCodeFromUrl !== userTenantCode) {
    return buildPathWithTenantCode(userTenantCode, to.path.replace(`/${tenantCodeFromUrl}`, ""))
  }

  // URL 中缺少租户编码（排除特殊路径）
  const skipPaths = ["/login", "/403"]
  if (!tenantCodeFromUrl && !skipPaths.some(p => to.path.startsWith(p))) {
    return buildPathWithTenantCode(userTenantCode, to.path)
  }

  return null
}

/**
 * 首次加载：有 Token 但无用户信息，尝试获取并设置路由
 */
async function handleFirstLoad(
  to: any,
  authStore: ReturnType<typeof useAuthStore>,
  tenantCodeFromUrl: string | null,
  next: any,
) {
  try {
    const userInfo = await authStore.fetchUserInfo()
    if (!userInfo) {
      authStore.logout()
      redirectToLogin(to, tenantCodeFromUrl, next)
      return
    }

    // 检查租户编码一致性
    const userTenantCode = userInfo.tenantCode
    if (userTenantCode) {
      if (tenantCodeFromUrl && tenantCodeFromUrl !== userTenantCode) {
        const corrected = buildPathWithTenantCode(
          userTenantCode, to.path.replace(`/${tenantCodeFromUrl}`, ""))
        next({ path: corrected, query: to.query, replace: true })
        return
      }
      if (!tenantCodeFromUrl) {
        const corrected = buildPathWithTenantCode(userTenantCode, to.path)
        next({ path: corrected, query: to.query, replace: true })
        return
      }
    }

    // 添加动态路由
    await addDynamicRoutes()
    const targetPath = to.fullPath
    const resolved = router.resolve(targetPath)

    // 如果目标是租户根路径，跳转到第一个菜单
    const isRootPath = to.matched.length === 1 && to.matched[0].name === "Main"
    if (isRootPath && authStore.menus?.length) {
      const first = findFirstMenuPath(authStore.menus)
      if (first) {
        const tc = tenantCodeFromUrl || authStore.user?.tenantCode
        if (tc) { next({ path: `/${tc}/${first}`, replace: true }); return }
      }
    }

    // 路由存在则重新导航
    if (resolved.name !== "NotFound") {
      next({ path: targetPath, replace: true })
    } else if (authStore.menus?.length) {
      const firstPath = findFirstMenuPath(authStore.menus)
      const tc = tenantCodeFromUrl || authStore.user?.tenantCode
      if (firstPath && tc) {
        next({ path: `/${tc}/${firstPath}`, replace: true })
      } else {
        next()
      }
    } else if (to.meta.requiresAuth === false) {
      next()
    } else {
      redirectToLogin(to, tenantCodeFromUrl, next)
    }
  } catch (error) {
    console.error("获取用户信息失败:", error)
    authStore.logout()
    redirectToLogin(to, tenantCodeFromUrl, next)
  }
}

/**
 * 首次添加动态路由后的处理
 */
async function handleRoutesFirstAdded(
  to: any,
  authStore: ReturnType<typeof useAuthStore>,
  tenantCodeFromUrl: string | null,
  next: any,
) {
  await nextTick()
  await nextTick()

  const targetPath = to.fullPath
  const resolved = router.resolve(targetPath)
  const isMainRoute = to.name === "Main"

  if (resolved.name !== "NotFound" && !isMainRoute) {
    next({ path: targetPath, replace: true })
    return
  }

  // 重定向到第一个菜单
  const firstPath = authStore.menus ? findFirstMenuPath(authStore.menus) : null
  const tc = tenantCodeFromUrl || authStore.user?.tenantCode
  if (firstPath && tc) {
    await nextTick()
    next({ path: `/${tc}/${firstPath}`, replace: true })
  } else {
    next({ name: "NotFound" })
  }
}

export default router
