import { MantineProvider, v8CssVariablesResolver } from "@mantine/core";
import { MarkdownViewer } from "@src/primitives/MarkdownViewer";
import { MANTINE_THEME } from "@src/theme/mantine";
import type { ReactElement } from "react";
import { renderToString } from "react-dom/server";
import { beforeAll, describe, expect, it } from "vitest";
import { md, mdViewer } from "../../_setup/markdown-classes";

// Mantine's `useComputedColorScheme` reaches for `window.matchMedia` even
// during a `renderToString` pass; stub it so the SSR test can exercise the
// full viewer pipeline (including `MarkdownCodeLines`).
beforeAll(() => {
    if (typeof window !== "undefined" && typeof window.matchMedia !== "function") {
        Object.defineProperty(window, "matchMedia", {
            writable: true,
            value: (query: string) => ({
                matches: false,
                media: query,
                onchange: null,
                addListener: () => {},
                removeListener: () => {},
                addEventListener: () => {},
                removeEventListener: () => {},
                dispatchEvent: () => false,
            }),
        });
    }
});

function shell(node: ReactElement): string {
    return renderToString(
        <MantineProvider
            theme={MANTINE_THEME}
            cssVariablesResolver={v8CssVariablesResolver}
            forceColorScheme="dark"
        >
            {node}
        </MantineProvider>,
    );
}

describe("MarkdownViewer / SSR", () => {
    it("renders to a static HTML string with semantic markdown structure", () => {
        const html = shell(
            <MarkdownViewer
                content={`# Title

Body with **bold**, *italic* and [a link](https://surrealdb.com).

- One
- Two

1. Alpha
2. Beta

\`\`\`ts
return true;
\`\`\`
`}
            />,
        );

        // Wrapper.
        expect(html).toContain(mdViewer.viewerRoot);

        // Semantic heading.
        expect(html).toContain(md.h1);
        expect(html).toMatch(/id="title"/);
        expect(html).toContain("Title");

        // Paragraph and inline marks (paragraph uses bare <p> without module class).
        expect(html).toMatch(/<p[^>]*>Body with/);
        expect(html).toContain(md.strong);
        expect(html).toContain("bold</strong>");
        expect(html).toContain(md.emphasis);
        expect(html).toContain(md.link);

        // Semantic lists.
        expect(html).toContain(md.list);
        expect(html).toContain("<li");

        // Semantic code block.
        expect(html).toContain(md.codeBlock);
        expect(html).toContain("<code");
        expect(html).toContain("</code></pre>");

        // Raw markdown markers must not leak through.
        expect(html).not.toContain("**bold**");
        expect(html).not.toContain("*italic*");
        expect(html).not.toContain("## ");
        expect(html).not.toMatch(/<p[^>]*>#/);
    });
});
