import { describe, it, expect, vi } from "vitest";
import { runColorConverter } from "./run";
import type { ToolContext } from "../../core/plugins/plugin-types";

describe("Color Converter", () => {
  const mockContext: ToolContext = {
    signal: new AbortController().signal,
    reportProgress: vi.fn(),
    logger: { info: vi.fn(), warn: vi.fn(), error: vi.fn() },
  };

  it("should parse a 6-digit hex color and return all formats", async () => {
    const result = await runColorConverter(
      { text: "#ff0000" },
      { format: "hex" },
      mockContext
    );
    expect(result.type).toBe("json");
    const value = (result as { type: "json"; value: Record<string, unknown> }).value;
    expect(value.hex).toBe("#ff0000");
    expect(value.rgb).toBe("rgb(255, 0, 0)");
    expect(value.channels).toEqual({ r: 255, g: 0, b: 0 });
    expect(value.primary).toBe("#ff0000");
  });

  it("should parse an RGB color string", async () => {
    const result = await runColorConverter(
      { text: "rgb(0, 128, 255)" },
      { format: "hex" },
      mockContext
    );
    const value = (result as { type: "json"; value: Record<string, unknown> }).value;
    expect(value.channels).toEqual({ r: 0, g: 128, b: 255 });
    expect(value.hex).toBe("#0080ff");
  });

  it("should parse an HSL color string", async () => {
    const result = await runColorConverter(
      { text: "hsl(0, 100%, 50%)" },
      { format: "rgb" },
      mockContext
    );
    const value = (result as { type: "json"; value: Record<string, unknown> }).value;
    const channels = value.channels as Record<string, unknown>;
    expect(channels.r).toBe(255);
    expect(channels.g).toBe(0);
    expect(channels.b).toBe(0);
    expect(value.primary).toBe("rgb(255, 0, 0)");
  });

  it("should parse a 3-digit shorthand hex", async () => {
    const result = await runColorConverter(
      { text: "#f00" },
      { format: "hex" },
      mockContext
    );
    const value = (result as { type: "json"; value: Record<string, unknown> }).value;
    expect(value.hex).toBe("#ff0000");
  });

  it("should parse hex without hash prefix", async () => {
    const result = await runColorConverter(
      { text: "00ff00" },
      { format: "rgb" },
      mockContext
    );
    const value = (result as { type: "json"; value: Record<string, unknown> }).value;
    expect(value.channels).toEqual({ r: 0, g: 255, b: 0 });
    expect(value.primary).toBe("rgb(0, 255, 0)");
  });

  it("should return primary in hsl format when requested", async () => {
    const result = await runColorConverter(
      { text: "#ffffff" },
      { format: "hsl" },
      mockContext
    );
    const value = (result as { type: "json"; value: Record<string, unknown> }).value;
    expect(value.primary).toContain("hsl(");
  });

  it("should throw on unrecognized color format", async () => {
    await expect(
      runColorConverter({ text: "not-a-color" }, { format: "hex" }, mockContext)
    ).rejects.toThrow("Unrecognized color format");
  });

  it("should throw on empty input", async () => {
    await expect(
      runColorConverter({ text: "" }, { format: "hex" }, mockContext)
    ).rejects.toThrow("No color value provided");
  });
});
