import { describe, expect, it } from "vitest";
import { parseArgs } from "./args.js";
import { buildChatRequest, composeMessage } from "./message.js";

describe("composeMessage", () => {
  it("returns text only", () => {
    expect(composeMessage({ text: "hello" })).toBe("hello");
  });

  it("returns file only with neutral label", () => {
    expect(composeMessage({ file: "foo.txt", fileContent: "contents" })).toBe(
      "Attached file (foo.txt):\ncontents",
    );
  });

  it("returns text + labeled file block", () => {
    expect(composeMessage({ text: "check this", file: "a.ts", fileContent: "const x = 1;" })).toBe(
      "check this\n\nAttached file (a.ts):\nconst x = 1;",
    );
  });

  it("handles missing fileContent gracefully", () => {
    expect(composeMessage({ file: "f.txt" })).toBe("Attached file (f.txt):\n");
  });

  it("uses basename for absolute paths", () => {
    expect(composeMessage({ file: "/tmp/opencode/demo/note.txt", fileContent: "hello" })).toBe(
      "Attached file (note.txt):\nhello",
    );
  });

  it("handles empty input", () => {
    expect(composeMessage({})).toBe("");
  });
});

describe("buildChatRequest", () => {
  it("maps fields correctly", () => {
    const req = buildChatRequest(
      {
        modelName: "cred/model",
        text: "hi",
        showReasoning: false,
      },
      { cwd: "/work", message: "hi" },
    );
    expect(req).toEqual({
      message: "hi",
      model: "cred/model",
      cwd: "/work",
    });
  });

  it("includes conversationId when provided", () => {
    const req = buildChatRequest(
      {
        modelName: "m",
        text: "x",
        conversationId: "conv-123",
        showReasoning: false,
      },
      { cwd: "/work", message: "x" },
    );
    expect(req.conversationId).toBe("conv-123");
  });

  it("omits conversationId when not provided", () => {
    const req = buildChatRequest(
      { modelName: "m", text: "x", showReasoning: false },
      { cwd: "/work", message: "x" },
    );
    expect(req).not.toHaveProperty("conversationId");
  });

  it("uses explicit cwd over context cwd", () => {
    const req = buildChatRequest(
      { modelName: "m", text: "x", cwd: "/explicit", showReasoning: false },
      { cwd: "/default", message: "x" },
    );
    expect(req.cwd).toBe("/explicit");
  });

  it("includes reasoningEffort when provided", () => {
    const req = buildChatRequest(
      { modelName: "m", text: "x", reasoningEffort: "xhigh", showReasoning: false },
      { cwd: "/work", message: "x" },
    );
    expect(req.reasoningEffort).toBe("xhigh");
  });

  it("omits reasoningEffort when not provided", () => {
    const req = buildChatRequest(
      { modelName: "m", text: "x", showReasoning: false },
      { cwd: "/work", message: "x" },
    );
    expect(req).not.toHaveProperty("reasoningEffort");
  });

  it("includes workspaceId when provided", () => {
    const req = buildChatRequest(
      { modelName: "m", text: "x", workspaceId: "my-work", showReasoning: false },
      { cwd: "/work", message: "x" },
    );
    expect(req.workspaceId).toBe("my-work");
  });

  it("omits workspaceId when not provided", () => {
    const req = buildChatRequest(
      { modelName: "m", text: "x", showReasoning: false },
      { cwd: "/work", message: "x" },
    );
    expect(req).not.toHaveProperty("workspaceId");
  });
});

describe("workspace flag → ChatRequest", () => {
  const defaultServer = "http://localhost:24203";

  it("--workspace flag sets workspaceId on request", () => {
    const parsed = parseArgs(["my-model", "--text", "hi", "--workspace", "my-work"], {
      defaultServer,
    });
    expect(parsed.kind).toBe("chat");
    if (parsed.kind !== "chat") return;
    const req = buildChatRequest(parsed, { cwd: "/work", message: "hi" });
    expect(req.workspaceId).toBe("my-work");
  });

  it("--workspace flag omitted sends no workspaceId", () => {
    const parsed = parseArgs(["my-model", "--text", "hi"], { defaultServer });
    expect(parsed.kind).toBe("chat");
    if (parsed.kind !== "chat") return;
    const req = buildChatRequest(parsed, { cwd: "/work", message: "hi" });
    expect(req.workspaceId).toBeUndefined();
    expect(req).not.toHaveProperty("workspaceId");
  });

  it("-w shorthand sets workspaceId on request", () => {
    const parsed = parseArgs(["my-model", "--text", "hi", "-w", "shorthand"], {
      defaultServer,
    });
    expect(parsed.kind).toBe("chat");
    if (parsed.kind !== "chat") return;
    const req = buildChatRequest(parsed, { cwd: "/work", message: "hi" });
    expect(req.workspaceId).toBe("shorthand");
  });
});
