import { beforeEach, describe, expect, it, vi } from "vitest"

const mocks = vi.hoisted(() => ({
  authMock: vi.fn(),
  redirectMock: vi.fn((target: string) => {
    throw new Error(`REDIRECT:${target}`)
  }),
}))

vi.mock("@/auth", () => ({
  auth: mocks.authMock,
}))

vi.mock("next/navigation", () => ({
  redirect: mocks.redirectMock,
}))

import DashboardPage from "@/app/(dashboard)/dashboard/page"

/**
 * 仪表盘路由分发测试
 *
 * 注意：实际代码用 `resolvePermissions(roles)` 从角色推导权限，
 * 而非读取 user.permissions 字段。因此 mock 中只需设置 roles，
 * 无需（也不应）设置 permissions 字段，以免误导。
 */
describe("dashboard route dispatcher", () => {
  beforeEach(() => {
    vi.resetAllMocks()
    mocks.redirectMock.mockImplementation((target: string) => {
      throw new Error(`REDIRECT:${target}`)
    })
  })

  it("redirects to login when session is missing", async () => {
    mocks.authMock.mockResolvedValue(null)
    await expect(DashboardPage()).rejects.toThrow("REDIRECT:/login")
  })

  it("redirects to login when user is missing", async () => {
    mocks.authMock.mockResolvedValue({ user: null })
    await expect(DashboardPage()).rejects.toThrow("REDIRECT:/login")
  })

  it("redirects admin to admin dashboard", async () => {
    mocks.authMock.mockResolvedValue({
      user: { id: "u_admin", roles: ["admin"] },
    })
    await expect(DashboardPage()).rejects.toThrow("REDIRECT:/admin/dashboard")
  })

  it("redirects student to student dashboard", async () => {
    mocks.authMock.mockResolvedValue({
      user: { id: "u_student", roles: ["student"] },
    })
    await expect(DashboardPage()).rejects.toThrow("REDIRECT:/student/dashboard")
  })

  it("redirects parent to parent dashboard", async () => {
    mocks.authMock.mockResolvedValue({
      user: { id: "u_parent", roles: ["parent"] },
    })
    await expect(DashboardPage()).rejects.toThrow("REDIRECT:/parent/dashboard")
  })

  it("redirects teacher to teacher dashboard", async () => {
    mocks.authMock.mockResolvedValue({
      user: { id: "u_teacher", roles: ["teacher"] },
    })
    await expect(DashboardPage()).rejects.toThrow("REDIRECT:/teacher/dashboard")
  })

  it("redirects unknown role to teacher dashboard (fallback)", async () => {
    mocks.authMock.mockResolvedValue({
      user: { id: "u_unknown", roles: [] },
    })
    await expect(DashboardPage()).rejects.toThrow("REDIRECT:/teacher/dashboard")
  })
})
