import { describe, it, expect } from "vitest";
import { ContentService } from "../content-service";

describe("ContentService", () => {
  const service = new ContentService();

  describe("renderMarkdown", () => {
    it("should render markdown to HTML", () => {
      const result = service.renderMarkdown("# Hello World");

      expect(result).toContain("<h1");
      expect(result).toContain("Hello World");
    });

    it("should render bold text", () => {
      const result = service.renderMarkdown("**bold**");

      expect(result).toContain("<strong>bold</strong>");
    });

    it("should render links", () => {
      const result = service.renderMarkdown("[link](https://example.com)");

      expect(result).toContain('<a href="https://example.com">link</a>');
    });

    it("should render code blocks", () => {
      const result = service.renderMarkdown("```js\nconst x = 1;\n```");

      expect(result).toContain("<pre><code");
    });
  });

  describe("extractFrontmatter", () => {
    it("should extract frontmatter from markdown", () => {
      const md = `---
title: Test Title
slug: test-slug
tags:
  - tag1
  - tag2
---

# Content`;

      const { frontmatter, rawContent } = service.extractFrontmatter(md);

      expect(frontmatter.title).toBe("Test Title");
      expect(frontmatter.slug).toBe("test-slug");
      expect(frontmatter.tags).toEqual(["tag1", "tag2"]);
      expect(rawContent.trim()).toBe("# Content");
    });

    it("should handle markdown without frontmatter", () => {
      const md = "# Just Content";

      const { frontmatter, rawContent } = service.extractFrontmatter(md);

      expect(frontmatter).toEqual({});
      expect(rawContent).toBe("# Just Content");
    });

    it("should handle frontmatter with categories", () => {
      const md = `---
title: Categories Test
categories:
  - 技术
  - 编程
---

Content here`;

      const { frontmatter, rawContent } = service.extractFrontmatter(md);

      expect(frontmatter.categories).toEqual(["技术", "编程"]);
      expect(rawContent.trim()).toBe("Content here");
    });

    it("should handle frontmatter with halo metadata", () => {
      const md = `---
title: Halo Post
halo:
  site: https://example.com
  name: abc-123
  publish: true
---

Content`;

      const { frontmatter } = service.extractFrontmatter(md);

      expect(frontmatter.halo?.site).toBe("https://example.com");
      expect(frontmatter.halo?.name).toBe("abc-123");
      expect(frontmatter.halo?.publish).toBe(true);
    });

    it("should handle empty frontmatter", () => {
      const md = `---
---

Content`;

      const { frontmatter, rawContent } = service.extractFrontmatter(md);

      expect(frontmatter).toEqual({});
      expect(rawContent.trim()).toBe("Content");
    });
  });

  describe("buildPostSpec", () => {
    it("should build post spec with default values", () => {
      const spec = service.buildPostSpec(
        "Test Title",
        "test-slug",
        "# Content",
        {},
        { rawType: "markdown", raw: "# Content", content: "<h1>Content</h1>" }
      );

      expect(spec.title).toBe("Test Title");
      expect(spec.slug).toBe("test-slug");
      expect(spec.allowComment).toBe(true);
      expect(spec.visible).toBe("PUBLIC");
      expect(spec.publish).toBe(false);
      expect(spec.excerpt.autoGenerate).toBe(true);
    });

    it("should use provided slug", () => {
      const spec = service.buildPostSpec(
        "Title",
        "custom-slug",
        "# Content",
        {},
        { rawType: "markdown", raw: "# Content", content: "<h1>Content</h1>" }
      );

      expect(spec.slug).toBe("custom-slug");
    });

    it("should auto-generate slug from title if not provided", () => {
      const spec = service.buildPostSpec(
        "Test Title",
        "",
        "# Content",
        {},
        { rawType: "markdown", raw: "# Content", content: "<h1>Content</h1>" }
      );

      // slugify should convert "Test Title" to "test-title"
      expect(spec.slug).toBeTruthy();
      expect(spec.slug).toContain("test");
    });

    it("should use excerpt from frontmatter", () => {
      const spec = service.buildPostSpec(
        "Title",
        "slug",
        "# Content",
        { excerpt: "Custom excerpt" },
        { rawType: "markdown", raw: "# Content", content: "<h1>Content</h1>" }
      );

      expect(spec.excerpt.autoGenerate).toBe(false);
      expect(spec.excerpt.raw).toBe("Custom excerpt");
    });

    it("should use cover from frontmatter", () => {
      const spec = service.buildPostSpec(
        "Title",
        "slug",
        "# Content",
        { cover: "https://example.com/cover.jpg" },
        { rawType: "markdown", raw: "# Content", content: "<h1>Content</h1>" }
      );

      expect(spec.cover).toBe("https://example.com/cover.jpg");
    });
  });
});