import { darkenHex, hexToHSL, hslToHex, lightenHex } from "./colours";

describe("hexToHSL", () => {
  it("should convert black hex to HSL", () => {
    const result = hexToHSL("#000000");
    expect(result).toEqual({ h: 0, s: 0, l: 0 });
  });

  it("should convert white hex to HSL", () => {
    const result = hexToHSL("#ffffff");
    expect(result).toEqual({ h: 0, s: 0, l: 100 });
  });

  it("should convert red hex to HSL", () => {
    const result = hexToHSL("#ff0000");
    expect(result).toEqual({ h: 0, s: 100, l: 50 });
  });

  it("should convert green hex to HSL", () => {
    const result = hexToHSL("#00ff00");
    expect(result).toEqual({ h: 120, s: 100, l: 50 });
  });

  it("should convert blue hex to HSL", () => {
    const result = hexToHSL("#0000ff");
    expect(result).toEqual({ h: 240, s: 100, l: 50 });
  });

  it("should handle hex without # prefix", () => {
    const result = hexToHSL("ff8800");
    expect(result).toEqual({ h: 32, s: 100, l: 50 });
  });

  it("should throw error for invalid hex format", () => {
    expect(() => hexToHSL("invalid")).toThrow("Invalid hex color format");
    expect(() => hexToHSL("#ffgg00")).toThrow("Invalid hex color format");
    expect(() => hexToHSL("#ff00")).toThrow("Invalid hex color format");
  });
});

describe("hslToHex", () => {
  it("should convert black HSL to hex", () => {
    const result = hslToHex(0, 0, 0);
    expect(result).toEqual("#000000");
  });

  it("should convert white HSL to hex", () => {
    const result = hslToHex(0, 0, 100);
    expect(result).toEqual("#ffffff");
  });

  it("should convert red HSL to hex", () => {
    const result = hslToHex(0, 100, 50);
    expect(result).toEqual("#ff0000");
  });

  it("should convert green HSL to hex", () => {
    const result = hslToHex(120, 100, 50);
    expect(result).toEqual("#00ff00");
  });

  it("should convert blue HSL to hex", () => {
    const result = hslToHex(240, 100, 50);
    expect(result).toEqual("#0000ff");
  });

  it("should convert orange HSL to hex", () => {
    const result = hslToHex(30, 100, 50);
    expect(result).toEqual("#ff8000");
  });

  it("should handle edge cases", () => {
    expect(hslToHex(360, 100, 50)).toEqual("#ff0000"); // 360 wraps to 0
    expect(hslToHex(-30, 100, 50)).toEqual("#ff0080"); // negative wraps
  });
});

describe("lightenHex", () => {
  it("should lighten a color by given percentage", () => {
    const result = lightenHex("#ff0000", 20);
    expect(result).toEqual("#ff6666");
  });

  it("should cap at 100% lightness", () => {
    const result = lightenHex("#ff0000", 60);
    expect(result).toEqual("#ffffff");
  });

  it("should not change color if percentage is 0", () => {
    const result = lightenHex("#ff0000", 0);
    expect(result).toEqual("#ff0000");
  });

  it("should work with already light colors", () => {
    const result = lightenHex("#ffcccc", 10); // hsl(0 100 90)
    expect(result).toEqual("#ffffff"); // hsl(0 100 100)
  });
});

describe("darkenHex", () => {
  it("should darken a color by given percentage", () => {
    const result = darkenHex("#ff0000", 20);
    expect(result).toEqual("#990000");
  });

  it("should cap at 0% lightness", () => {
    const result = darkenHex("#ff0000", 60);
    expect(result).toEqual("#000000");
  });

  it("should not change color if percentage is 0", () => {
    const result = darkenHex("#ff0000", 0);
    expect(result).toEqual("#ff0000");
  });

  it("should work with already dark colors", () => {
    const result = darkenHex("#330000", 10);
    expect(result).toEqual("#000000");
  });
});
