import {
  isISOLocal,
  offsetToISO8601,
  toISOLocal,
  hasRepeatedIds,
} from "./utils";

describe("Utils", () => {
  describe("ISO Formatter", () => {
    it("Should format a positive, no minutes offset", async () => {
      expect(offsetToISO8601(120)).toEqual("-02:00");
    });

    it("Should format a negative, no minutes offset", async () => {
      expect(offsetToISO8601(-120)).toEqual("+02:00");
    });

    it("Should format a positive offset with minutes", async () => {
      expect(offsetToISO8601(123)).toEqual("-02:03");
    });

    it("Should format a positive offset with minutes (II)", async () => {
      expect(offsetToISO8601(143)).toEqual("-02:23");
    });
    it("Should format a positive offset with minutes (III) - hour more than one digit", async () => {
      expect(offsetToISO8601(643)).toEqual("-10:43");
    });
  });

  describe("ISO checker", () => {
    it("Should detect a timestamp as a correct RFC 3339 long format", () => {
      console.log(toISOLocal(new Date()));
      expect(isISOLocal(toISOLocal(new Date()))).toBeTruthy();
    });
    it("Should detect a timestamp as a correct RFC 3339 long format", () => {
      expect(isISOLocal("1937-01-01T12:00:27.87+00:20")).toBeTruthy();
    });

    it("Should detect a random string is not a correct RFC 3339 long format", () => {
      expect(isISOLocal("asdsafasfsafd")).toBeFalsy();
    });

    it("Should detect a valid date is not a correct RFC 3339 long format", () => {
      expect(isISOLocal("1937-01-01")).toBeFalsy();
    });

    it("Should detect a valid date and time is not a correct RFC 3339 long format", () => {
      expect(isISOLocal("1937-01-01T12:00:27")).toBeFalsy();
    });

    it("Should detect a unix timestamp is not a correct RFC 3339 long format", () => {
      expect(isISOLocal("1663231725773")).toBeFalsy();
    });

    it("Should detect a valid rfc3339 short is not a correct RFC 3339 long format", () => {
      expect(isISOLocal("1990-12-31T15:59:60-08:00")).toBeFalsy();
    });
  });

  describe("hasRepeatedIds", () => {
    it("returns false for empty array", () => {
      const arr: any[] = [];
      expect(hasRepeatedIds(arr)).toBe(false);
    });
    it("returns false for array with one item", () => {
      expect(hasRepeatedIds([1])).toBe(false);
    });
    it("returns true for array with duplicate primitives", () => {
      expect(hasRepeatedIds([1, 2, 3, 2])).toBe(true);
    });
    it("returns false for array with unique primitives", () => {
      expect(hasRepeatedIds([1, 2, 3])).toBe(false);
    });
    it("returns true for array with duplicate objects (shallow)", () => {
      expect(hasRepeatedIds([{ a: 1 }, { a: 2 }, { a: 1 }])).toBe(true);
    });
    it("returns false for array with unique objects", () => {
      expect(hasRepeatedIds([{ a: 1 }, { a: 2 }, { a: 3 }])).toBe(false);
    });
    it("returns true for mixed types with duplicates", () => {
      expect(hasRepeatedIds([1, "a", { b: 2 }, "a"])).toBe(true);
    });
    it("returns false for mixed types with no duplicates", () => {
      expect(hasRepeatedIds([1, "a", { b: 2 }, { b: 3 }])).toBe(false);
    });
    it("returns true for duplicate arrays (shallow)", () => {
      expect(
        hasRepeatedIds([
          [1, 2],
          [1, 2],
        ])
      ).toBe(true);
    });
    it("returns false for unique arrays", () => {
      expect(
        hasRepeatedIds([
          [1, 2],
          [2, 1],
        ])
      ).toBe(false);
    });
  });
});
