/**
 * @jest-environment node
 */

import { NextRequest } from "next/server";
import { POST } from "../route";

jest.mock("@clerk/nextjs/server", () => ({
  auth: jest.fn(),
}));

jest.mock("@/lib/database", () => ({
  getDatabase: jest.fn(),
}));

jest.mock("@/lib/sync-user", () => ({
  ensureUserSynced: jest.fn(),
}));

jest.mock("@/lib/clerk-helpers", () => ({
  setUserRole: jest.fn(),
}));

describe("POST /api/admin/set-role", () => {
  const mockAuth = require("@clerk/nextjs/server").auth as jest.Mock;
  const mockGetDatabase = require("@/lib/database").getDatabase as jest.Mock;
  const mockEnsureUserSynced = require("@/lib/sync-user")
    .ensureUserSynced as jest.Mock;
  const mockSetUserRole = require("@/lib/clerk-helpers")
    .setUserRole as jest.Mock;

  const mockDb = {
    getUserById: jest.fn(),
  };

  beforeEach(() => {
    jest.clearAllMocks();
    mockGetDatabase.mockResolvedValue(mockDb);
  });

  it("returns 403 when admin tries to assign role across gyms", async () => {
    mockAuth.mockResolvedValue({ userId: "admin_1" });
    mockEnsureUserSynced.mockResolvedValue({
      id: "admin_1",
      role: "admin",
      gymId: "gym_a",
    });
    mockDb.getUserById.mockResolvedValue({
      id: "user_2",
      role: "client",
      gymId: "gym_b",
    });

    const request = new NextRequest("http://localhost/api/admin/set-role", {
      method: "POST",
      body: JSON.stringify({
        targetUserId: "user_2",
        role: "trainer",
      }),
    });

    const response = await POST(request);

    expect(response.status).toBe(403);
    expect(mockSetUserRole).not.toHaveBeenCalled();
  });

  it("allows superAdmin to assign roles across gyms", async () => {
    mockAuth.mockResolvedValue({ userId: "super_1" });
    mockEnsureUserSynced.mockResolvedValue({
      id: "super_1",
      role: "superAdmin",
      gymId: null,
    });
    mockDb.getUserById.mockResolvedValue({
      id: "user_2",
      role: "client",
      gymId: "gym_b",
    });
    mockSetUserRole.mockResolvedValue({
      id: "user_2",
      emailAddresses: [{ emailAddress: "user2@example.com" }],
      firstName: "User",
      lastName: "Two",
      publicMetadata: { role: "admin" },
    });

    const request = new NextRequest("http://localhost/api/admin/set-role", {
      method: "POST",
      body: JSON.stringify({
        targetUserId: "user_2",
        role: "admin",
      }),
    });

    const response = await POST(request);
    const payload = await response.json();

    expect(response.status).toBe(200);
    expect(payload.success).toBe(true);
    expect(mockSetUserRole).toHaveBeenCalledWith("user_2", "admin");
  });
});
