/**
 * @jest-environment node
 */

import { GET } 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("@fitai/database", () => ({
  eq: jest.fn(() => ({})),
  sql: jest.fn((strings: TemplateStringsArray) => strings.join("")),
  db: {
    run: jest.fn(),
    select: jest.fn(() => ({
      from: jest.fn(() => ({
        where: jest.fn(() => ({
          orderBy: jest.fn(() => ({
            all: jest.fn().mockResolvedValue([
              { id: "gym_a", status: "active", name: "Gym A" },
              { id: "gym_b", status: "active", name: "Gym B" },
            ]),
          })),
        })),
      })),
    })),
    gyms: {
      status: "active",
    },
    users: {},
  },
  gyms: {
    status: "active",
  },
  users: {},
}));

describe("GET /api/gyms authz", () => {
  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;

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

  it("returns only own gym for admin", async () => {
    mockAuth.mockResolvedValue({ userId: "admin_1" });
    mockEnsureUserSynced.mockResolvedValue({
      id: "admin_1",
      role: "admin",
      gymId: "gym_a",
    });

    const response = await GET();
    const data = await response.json();

    expect(response.status).toBe(200);
    expect(data).toHaveLength(1);
    expect(data[0].id).toBe("gym_a");
  });

  it("returns all gyms for superAdmin", async () => {
    mockAuth.mockResolvedValue({ userId: "super_1" });
    mockEnsureUserSynced.mockResolvedValue({
      id: "super_1",
      role: "superAdmin",
      gymId: null,
    });

    const response = await GET();
    const data = await response.json();

    expect(response.status).toBe(200);
    expect(data).toHaveLength(2);
  });
});
