import { describe, test, expect } from "bun:test";
import { CwMemberController } from "../../../src/controllers/CwMemberController";

// ---------------------------------------------------------------------------
// Helpers
// ---------------------------------------------------------------------------

function buildMockCwMember(overrides: Record<string, any> = {}) {
  return {
    id: "member-1",
    cwMemberId: 42,
    identifier: "jdoe",
    firstName: "John",
    lastName: "Doe",
    officeEmail: "jdoe@example.com",
    inactiveFlag: false,
    apiKey: null,
    cwLastUpdated: new Date("2026-02-01"),
    createdAt: new Date("2026-01-01"),
    updatedAt: new Date("2026-02-01"),
    ...overrides,
  };
}

// ---------------------------------------------------------------------------
// Tests
// ---------------------------------------------------------------------------

describe("CwMemberController", () => {
  // -----------------------------------------------------------------
  // Constructor
  // -----------------------------------------------------------------
  describe("constructor", () => {
    test("sets all public properties from data", () => {
      const data = buildMockCwMember();
      const ctrl = new CwMemberController(data as any);

      expect(ctrl.id).toBe("member-1");
      expect(ctrl.cwMemberId).toBe(42);
      expect(ctrl.identifier).toBe("jdoe");
      expect(ctrl.firstName).toBe("John");
      expect(ctrl.lastName).toBe("Doe");
      expect(ctrl.officeEmail).toBe("jdoe@example.com");
      expect(ctrl.inactiveFlag).toBe(false);
      expect(ctrl.apiKey).toBeNull();
      expect(ctrl.cwLastUpdated).toEqual(new Date("2026-02-01"));
      expect(ctrl.createdAt).toEqual(new Date("2026-01-01"));
      expect(ctrl.updatedAt).toEqual(new Date("2026-02-01"));
    });

    test("handles null officeEmail", () => {
      const data = buildMockCwMember({ officeEmail: null });
      const ctrl = new CwMemberController(data as any);
      expect(ctrl.officeEmail).toBeNull();
    });

    test("handles apiKey set", () => {
      const data = buildMockCwMember({ apiKey: "secret-key" });
      const ctrl = new CwMemberController(data as any);
      expect(ctrl.apiKey).toBe("secret-key");
    });
  });

  // -----------------------------------------------------------------
  // fullName getter
  // -----------------------------------------------------------------
  describe("fullName", () => {
    test("returns firstName + lastName", () => {
      const ctrl = new CwMemberController(buildMockCwMember() as any);
      expect(ctrl.fullName).toBe("John Doe");
    });

    test("returns trimmed name when lastName is empty", () => {
      const ctrl = new CwMemberController(
        buildMockCwMember({ lastName: "" }) as any
      );
      expect(ctrl.fullName).toBe("John");
    });

    test("returns trimmed name when firstName is empty", () => {
      const ctrl = new CwMemberController(
        buildMockCwMember({ firstName: "" }) as any
      );
      expect(ctrl.fullName).toBe("Doe");
    });

    test("falls back to identifier when both names are empty", () => {
      const ctrl = new CwMemberController(
        buildMockCwMember({ firstName: "", lastName: "" }) as any
      );
      expect(ctrl.fullName).toBe("jdoe");
    });
  });

  // -----------------------------------------------------------------
  // toJson
  // -----------------------------------------------------------------
  describe("toJson", () => {
    test("returns all fields including fullName", () => {
      const ctrl = new CwMemberController(buildMockCwMember() as any);
      const json = ctrl.toJson();

      expect(json.id).toBe("member-1");
      expect(json.cwMemberId).toBe(42);
      expect(json.identifier).toBe("jdoe");
      expect(json.firstName).toBe("John");
      expect(json.lastName).toBe("Doe");
      expect(json.fullName).toBe("John Doe");
      expect(json.officeEmail).toBe("jdoe@example.com");
      expect(json.inactiveFlag).toBe(false);
      expect(json.apiKey).toBeNull();
      expect(json.cwLastUpdated).toEqual(new Date("2026-02-01"));
      expect(json.createdAt).toEqual(new Date("2026-01-01"));
      expect(json.updatedAt).toEqual(new Date("2026-02-01"));
    });

    test("includes fullName in JSON", () => {
      const ctrl = new CwMemberController(
        buildMockCwMember({ firstName: "", lastName: "" }) as any
      );
      expect(ctrl.toJson().fullName).toBe("jdoe");
    });
  });
});
