import { describe, expect, it } from "vitest";
import { validateTagDraft } from "./model";

describe("validateTagDraft", () => {
  it("accepts a valid name + hex colour, trimming the name and lowercasing the hex", () => {
    expect(validateTagDraft({ name: "  Void  ", colour: "#7C3AED" }, [])).toEqual({
      ok: true,
      tag: { name: "Void", colour: "#7c3aed" },
    });
  });

  it("rejects a blank name (empty or whitespace-only)", () => {
    expect(validateTagDraft({ name: "   ", colour: "#7c3aed" }, [])).toEqual({
      ok: false,
      error: "Tag name is required",
    });
  });

  it("rejects a name longer than 30 characters (after trimming)", () => {
    const long = "a".repeat(31);
    expect(validateTagDraft({ name: long, colour: "#7c3aed" }, [])).toEqual({
      ok: false,
      error: "Tag name must be 30 characters or fewer",
    });
  });

  it("accepts a name of exactly 30 characters (boundary)", () => {
    const name = "a".repeat(30);
    expect(validateTagDraft({ name, colour: "#7c3aed" }, [])).toEqual({
      ok: true,
      tag: { name, colour: "#7c3aed" },
    });
  });

  it("rejects a name that duplicates an existing one, case-insensitively", () => {
    expect(
      validateTagDraft({ name: "  VOID ", colour: "#7c3aed" }, ["Void", "Phase 1"]),
    ).toEqual({ ok: false, error: "A tag with this name already exists" });
  });

  it("accepts a name that clashes with no existing tag (edit excludes its own name)", () => {
    // On edit the caller passes the OTHER tags' names, so keeping/​recasing the
    // tag's own name is allowed.
    expect(
      validateTagDraft({ name: "Void", colour: "#7c3aed" }, ["Phase 1"]),
    ).toEqual({ ok: true, tag: { name: "Void", colour: "#7c3aed" } });
  });

  it("rejects a colour that is not a hex code", () => {
    expect(validateTagDraft({ name: "Void", colour: "red" }, [])).toEqual({
      ok: false,
      error: "Colour must be a hex code like #7c3aed",
    });
  });

  it("accepts a 3-digit hex shorthand, normalised to lowercase", () => {
    expect(validateTagDraft({ name: "Void", colour: "#ABC" }, [])).toEqual({
      ok: true,
      tag: { name: "Void", colour: "#abc" },
    });
  });
});
