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

import { AdminDevicesOverview } from "@/components/admin/devices/admin-devices-overview"
import { AdminCompaniesManager } from "@/components/admin/companies/admin-companies-manager"
import { AdminUsersWorkspace } from "@/components/admin/users/admin-users-workspace"

// Shared mocks for server-side helpers
const requireStaffSession = vi.fn()
const fetchCompaniesByTenant = vi.fn()
const normalizeCompany = vi.fn((c) => c)
const prismaUserFindMany = vi.fn()
const prismaAuthUserFindMany = vi.fn()
const prismaAuthSessionFindMany = vi.fn()

vi.mock("@/lib/auth-server", () => ({
  requireStaffSession,
}))

vi.mock("@/server/company-service", () => ({
  fetchCompaniesByTenant,
  normalizeCompany,
}))

vi.mock("@/lib/prisma", () => ({
  prisma: {
    user: { findMany: prismaUserFindMany },
    authUser: { findMany: prismaAuthUserFindMany },
    authSession: { findMany: prismaAuthSessionFindMany },
  },
}))

// Helpers
function getSingleChild(element: ReactElement): ReactElement {
  const child = (element.props as { children?: ReactElement | ReactElement[] }).children
  if (!child) throw new Error("Expected element to have children")
  return Array.isArray(child) ? child[0] : child
}

describe("admin quick actions -> auto-open flags", () => {
  describe("devices page", () => {
    it("passes autoOpenCreateDevice=true when quick=new-device", async () => {
      const { default: AdminDevicesPage } = await import("./devices/page")

      const element = (await AdminDevicesPage({
        searchParams: Promise.resolve({ quick: "new-device" }),
      } as unknown as { searchParams: Promise<Record<string, string | string[] | undefined>> })) as ReactElement

      const outerDiv = getSingleChild(element)
      const overview = getSingleChild(outerDiv)

      expect(overview.type).toBe(AdminDevicesOverview)
      expect(overview.props.autoOpenCreateDevice).toBe(true)
    })

    it("passes autoOpenCreateDevice=false when quick is missing", async () => {
      const { default: AdminDevicesPage } = await import("./devices/page")

      const element = (await AdminDevicesPage({
        searchParams: Promise.resolve({}),
      } as unknown as { searchParams: Promise<Record<string, string | string[] | undefined>> })) as ReactElement

      const outerDiv = getSingleChild(element)
      const overview = getSingleChild(outerDiv)

      expect(overview.type).toBe(AdminDevicesOverview)
      expect(overview.props.autoOpenCreateDevice).toBe(false)
    })
  })

  describe("companies page", () => {
    beforeEach(() => {
      requireStaffSession.mockResolvedValue({
        user: { tenantId: "tenant-1" },
      })
      fetchCompaniesByTenant.mockResolvedValue([])
      normalizeCompany.mockImplementation((c) => c)
    })

    it("passes autoOpenCreate=true when quick=new-company", async () => {
      const { default: AdminCompaniesPage } = await import("./companies/page")

      const element = (await AdminCompaniesPage({
        searchParams: Promise.resolve({ quick: "new-company" }),
      } as unknown as { searchParams: Promise<Record<string, string | string[] | undefined>> })) as ReactElement

      const outerDiv = getSingleChild(element)
      const manager = getSingleChild(outerDiv)

      expect(manager.type).toBe(AdminCompaniesManager)
      expect(manager.props.autoOpenCreate).toBe(true)
    })

    it("passes autoOpenCreate=false when quick is missing", async () => {
      const { default: AdminCompaniesPage } = await import("./companies/page")

      const element = (await AdminCompaniesPage({
        searchParams: Promise.resolve({}),
      } as unknown as { searchParams: Promise<Record<string, string | string[] | undefined>> })) as ReactElement

      const outerDiv = getSingleChild(element)
      const manager = getSingleChild(outerDiv)

      expect(manager.type).toBe(AdminCompaniesManager)
      expect(manager.props.autoOpenCreate).toBe(false)
    })
  })

  describe("users page", () => {
    beforeEach(() => {
      requireStaffSession.mockResolvedValue({
        user: { tenantId: "tenant-1" },
      })
      prismaUserFindMany.mockResolvedValue([])
      prismaAuthUserFindMany.mockResolvedValue([])
      prismaAuthSessionFindMany.mockResolvedValue([])
      fetchCompaniesByTenant.mockResolvedValue([])
      normalizeCompany.mockImplementation((c) => c)
    })

    it("passes autoOpenCreate=true when quick=new-user", async () => {
      const { default: AdminUsersPage } = await import("./users/page")

      const element = (await AdminUsersPage({
        searchParams: Promise.resolve({ quick: "new-user" }),
      } as unknown as { searchParams: Promise<Record<string, string | string[] | undefined>> })) as ReactElement

      const outerDiv = getSingleChild(element)
      const workspace = getSingleChild(outerDiv)

      expect(workspace.type).toBe(AdminUsersWorkspace)
      expect(workspace.props.autoOpenCreate).toBe(true)
    })

    it("passes autoOpenCreate=false when quick is missing", async () => {
      const { default: AdminUsersPage } = await import("./users/page")

      const element = (await AdminUsersPage({
        searchParams: Promise.resolve({}),
      } as unknown as { searchParams: Promise<Record<string, string | string[] | undefined>> })) as ReactElement

      const outerDiv = getSingleChild(element)
      const workspace = getSingleChild(outerDiv)

      expect(workspace.type).toBe(AdminUsersWorkspace)
      expect(workspace.props.autoOpenCreate).toBe(false)
    })
  })
})
