import { describe, expect, it } from "vitest";
import { isPlainTextSurface, sanitizeForPlainText } from "./sanitize-text.js";

// ---------------------------------------------------------------------------
// isPlainTextSurface
// ---------------------------------------------------------------------------

describe("isPlainTextSurface", () => {
  it.each(["whatsapp", "signal", "sms", "irc", "telegram", "imessage", "googlechat"])(
    "returns true for %s",
    (channel) => {
      expect(isPlainTextSurface(channel)).toBe(true);
    },
  );

  it.each(["discord", "slack", "web", "matrix"])("returns false for %s", (channel) => {
    expect(isPlainTextSurface(channel)).toBe(false);
  });

  it("is case-insensitive", () => {
    expect(isPlainTextSurface("WhatsApp")).toBe(true);
    expect(isPlainTextSurface("SIGNAL")).toBe(true);
  });
});

// ---------------------------------------------------------------------------
// sanitizeForPlainText
// ---------------------------------------------------------------------------

describe("sanitizeForPlainText", () => {
  // --- line breaks --------------------------------------------------------

  it("converts <br> to newline", () => {
    expect(sanitizeForPlainText("hello<br>world")).toBe("hello\nworld");
  });

  it("converts self-closing <br/> and <br /> variants", () => {
    expect(sanitizeForPlainText("a<br/>b")).toBe("a\nb");
    expect(sanitizeForPlainText("a<br />b")).toBe("a\nb");
  });

  // --- inline formatting --------------------------------------------------

  it("converts <b> and <strong> to WhatsApp bold", () => {
    expect(sanitizeForPlainText("<b>bold</b>")).toBe("*bold*");
    expect(sanitizeForPlainText("<strong>bold</strong>")).toBe("*bold*");
  });

  it("converts <i> and <em> to WhatsApp italic", () => {
    expect(sanitizeForPlainText("<i>italic</i>")).toBe("_italic_");
    expect(sanitizeForPlainText("<em>italic</em>")).toBe("_italic_");
  });

  it("converts <s>, <strike>, and <del> to WhatsApp strikethrough", () => {
    expect(sanitizeForPlainText("<s>deleted</s>")).toBe("~deleted~");
    expect(sanitizeForPlainText("<del>removed</del>")).toBe("~removed~");
    expect(sanitizeForPlainText("<strike>old</strike>")).toBe("~old~");
  });

  it("converts <code> to backtick wrapping", () => {
    expect(sanitizeForPlainText("<code>foo()</code>")).toBe("`foo()`");
  });

  // --- block elements -----------------------------------------------------

  it("converts <p> and <div> to newlines", () => {
    expect(sanitizeForPlainText("<p>paragraph</p>")).toBe("\nparagraph\n");
  });

  it("converts headings to bold text with newlines", () => {
    expect(sanitizeForPlainText("<h1>Title</h1>")).toBe("\n*Title*\n");
    expect(sanitizeForPlainText("<h3>Section</h3>")).toBe("\n*Section*\n");
  });

  it("converts <li> to bullet points", () => {
    expect(sanitizeForPlainText("<li>item one</li><li>item two</li>")).toBe(
      "• item one\n• item two\n",
    );
  });

  // --- tag stripping ------------------------------------------------------

  it("strips unknown/remaining tags", () => {
    expect(sanitizeForPlainText('<span class="x">text</span>')).toBe("text");
    expect(sanitizeForPlainText('<a href="https://example.com">link</a>')).toBe("link");
  });

  it("preserves angle-bracket autolinks", () => {
    expect(sanitizeForPlainText("See <https://example.com/path?q=1> now")).toBe(
      "See https://example.com/path?q=1 now",
    );
  });

  // --- passthrough --------------------------------------------------------

  it("passes through clean text unchanged", () => {
    expect(sanitizeForPlainText("hello world")).toBe("hello world");
  });

  it("does not corrupt angle brackets in prose", () => {
    // `a < b` does not match `<tag>` pattern because there is no closing `>`
    // immediately after a tag-like sequence.
    expect(sanitizeForPlainText("a < b && c > d")).toBe("a < b && c > d");
  });

  // --- mixed content ------------------------------------------------------

  it("handles mixed HTML content", () => {
    const input = "Hello<br><b>world</b> this is <i>nice</i>";
    expect(sanitizeForPlainText(input)).toBe("Hello\n*world* this is _nice_");
  });

  it("collapses excessive newlines", () => {
    expect(sanitizeForPlainText("a<br><br><br><br>b")).toBe("a\n\nb");
  });
});
