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

const { redirectMock, resolveRoleFromServerContextMock, hasOwnerUserMock } = vi.hoisted(() => ({
  redirectMock: vi.fn((path: string) => {
    throw new Error(`REDIRECT:${path}`)
  }),
  resolveRoleFromServerContextMock: vi.fn(),
  hasOwnerUserMock: vi.fn(),
}))

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

vi.mock("@/lib/access-server", () => ({
  resolveRoleFromServerContext: resolveRoleFromServerContextMock,
}))

vi.mock("@/lib/auth/server", () => ({
  hasOwnerUser: hasOwnerUserMock,
}))

vi.mock("./login-form", () => ({
  LoginForm: ({ mode }: { mode: string }) => ({ type: "login-form", props: { mode } }),
}))

import LoginPage from "./page"

function expectRedirect(call: () => Promise<unknown>, path: string) {
  return expect(call()).rejects.toThrow(`REDIRECT:${path}`)
}

describe("login page", () => {
  beforeEach(() => {
    redirectMock.mockClear()
    resolveRoleFromServerContextMock.mockReset()
    hasOwnerUserMock.mockReset()
  })

  it("redirects authenticated users to dashboard", async () => {
    resolveRoleFromServerContextMock.mockResolvedValue("manager")

    await expectRedirect(() => LoginPage({ searchParams: Promise.resolve({}) }), "/")
  })

  it("redirects to welcome if owner is missing", async () => {
    resolveRoleFromServerContextMock.mockResolvedValue(null)
    hasOwnerUserMock.mockResolvedValue(false)

    await expectRedirect(
      () => LoginPage({ searchParams: Promise.resolve({ next: "/settings" }) }),
      "/welcome?next=%2Fsettings",
    )
  })

  it("renders sign-in mode once owner exists", async () => {
    resolveRoleFromServerContextMock.mockResolvedValue(null)
    hasOwnerUserMock.mockResolvedValue(true)

    const page = (await LoginPage({ searchParams: Promise.resolve({}) })) as ReactElement<{
      mode: string
    }>

    expect(page.props.mode).toBe("signin")
  })
})
