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

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

  it("should convert headings h1, h2, h3", async () => {
    const result = await runMarkdownToHtml(
      { text: "# Hello\n## World\n### Sub" },
      {},
      mockContext
    );
    expect(result.type).toBe("text");
    const value = (result as { type: "text"; value: string }).value;
    expect(value).toContain("<h1>Hello</h1>");
    expect(value).toContain("<h2>World</h2>");
    expect(value).toContain("<h3>Sub</h3>");
  });

  it("should convert bold and italic text", async () => {
    const result = await runMarkdownToHtml(
      { text: "This is **bold** and *italic* and ***both***" },
      {},
      mockContext
    );
    const value = (result as { type: "text"; value: string }).value;
    expect(value).toContain("<strong>bold</strong>");
    expect(value).toContain("<em>italic</em>");
    expect(value).toContain("<strong><em>both</em></strong>");
  });

  it("should convert inline code", async () => {
    const result = await runMarkdownToHtml(
      { text: "Use `console.log` to debug" },
      {},
      mockContext
    );
    const value = (result as { type: "text"; value: string }).value;
    expect(value).toContain("<code>console.log</code>");
  });

  it("should convert links", async () => {
    const result = await runMarkdownToHtml(
      { text: "Visit [Google](https://google.com)" },
      {},
      mockContext
    );
    const value = (result as { type: "text"; value: string }).value;
    expect(value).toContain('<a href="https://google.com">Google</a>');
  });

  it("should convert images", async () => {
    const result = await runMarkdownToHtml(
      { text: "![Alt text](image.png)" },
      {},
      mockContext
    );
    const value = (result as { type: "text"; value: string }).value;
    expect(value).toContain('<img src="image.png" alt="Alt text">');
  });

  it("should convert horizontal rules", async () => {
    const result = await runMarkdownToHtml(
      { text: "Above\n---\nBelow" },
      {},
      mockContext
    );
    const value = (result as { type: "text"; value: string }).value;
    expect(value).toContain("<hr>");
  });

  it("should convert unordered lists", async () => {
    const result = await runMarkdownToHtml(
      { text: "- item 1\n- item 2\n- item 3" },
      {},
      mockContext
    );
    const value = (result as { type: "text"; value: string }).value;
    expect(value).toContain("<ul>");
    expect(value).toContain("<li>item 1</li>");
    expect(value).toContain("<li>item 2</li>");
    expect(value).toContain("<li>item 3</li>");
    expect(value).toContain("</ul>");
  });

  it("should convert strikethrough", async () => {
    const result = await runMarkdownToHtml(
      { text: "This is ~~deleted~~ text" },
      {},
      mockContext
    );
    const value = (result as { type: "text"; value: string }).value;
    expect(value).toContain("<del>deleted</del>");
  });

  it("should throw on empty input", async () => {
    await expect(
      runMarkdownToHtml({ text: "" }, {}, mockContext)
    ).rejects.toThrow("No Markdown text provided");
  });
});
