import { describe, test, expect } from "bun:test";
import { RoleController } from "../../../src/controllers/RoleController";
import { buildMockRole, buildMockUser } from "../../setup";

describe("RoleController", () => {
  // -------------------------------------------------------------------
  // Constructor
  // -------------------------------------------------------------------
  describe("constructor", () => {
    test("sets public properties from role data", () => {
      const data = buildMockRole();
      const ctrl = new RoleController(data);
      expect(ctrl.id).toBe("role-1");
      expect(ctrl.title).toBe("Test Role");
      expect(ctrl.moniker).toBe("test-role");
      expect(ctrl.deleted).toBe(false);
    });

    test("sets timestamps", () => {
      const ctrl = new RoleController(buildMockRole());
      expect(ctrl.createdAt).toBeInstanceOf(Date);
      expect(ctrl.updatedAt).toBeInstanceOf(Date);
    });
  });

  // -------------------------------------------------------------------
  // getUsers
  // -------------------------------------------------------------------
  describe("getUsers()", () => {
    test("returns empty collection when no users", () => {
      const ctrl = new RoleController(buildMockRole({ users: [] }));
      const users = ctrl.getUsers();
      expect(users.size).toBe(0);
    });

    test("returns collection of UserController instances", () => {
      const userData = buildMockUser({ id: "u-1" });
      const ctrl = new RoleController(buildMockRole({ users: [userData] }));
      const users = ctrl.getUsers();
      expect(users.size).toBe(1);
      expect(users.get("u-1")).toBeDefined();
    });
  });

  // -------------------------------------------------------------------
  // toJson
  // -------------------------------------------------------------------
  describe("toJson()", () => {
    test("returns base JSON without permissions or users by default", () => {
      const ctrl = new RoleController(buildMockRole());
      const json = ctrl.toJson();
      expect(json.id).toBe("role-1");
      expect(json.title).toBe("Test Role");
      expect(json.moniker).toBe("test-role");
      expect(json.permissions).toBeUndefined();
      expect(json.users).toBeUndefined();
      expect(json.createdAt).toBeDefined();
      expect(json.updatedAt).toBeDefined();
    });

    test("includes users when viewUsers is true", () => {
      const userData = buildMockUser({
        id: "u-1",
        roles: [{ id: "role-1", moniker: "test-role" }],
      });
      const ctrl = new RoleController(buildMockRole({ users: [userData] }));
      const json = ctrl.toJson({ viewUsers: true });
      expect(json.users).toBeDefined();
      expect(json.users).toHaveLength(1);
      expect(json.users![0]!.id).toBe("u-1");
    });
  });
});
