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";

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>,
    );
}

// Syntax highlighting splits a line into per-token spans, so assert on single
// identifier tokens that survive tokenisation rather than whole expressions.
describe("MarkdownViewer / code inside lists", () => {
    it("renders a fenced code block nested in a list item", () => {
        const content = ["- Item with code:", "  ```js", "  alphaVar;", "  ```"].join("\n");
        const html = shell(<MarkdownViewer content={content} />);
        expect(html).toContain("alphaVar");
    });

    it("renders multiple code lines nested in a list item", () => {
        const content = ["- Item:", "  ```js", "  alphaVar;", "  betaVar;", "  ```"].join("\n");
        const html = shell(<MarkdownViewer content={content} />);
        expect(html).toContain("alphaVar");
        expect(html).toContain("betaVar");
    });

    it("renders a code block that is the first child of a list item", () => {
        const content = ["- ```ts", "  codeFirstVar;", "  ```"].join("\n");
        const html = shell(<MarkdownViewer content={content} />);
        expect(html).toContain("codeFirstVar");
    });

    it("renders a fenced code block inside a task list item", () => {
        const content = ["- [ ] Task with code", "  ```js", "  taskCodeVar;", "  ```"].join("\n");
        const html = shell(<MarkdownViewer content={content} />);
        expect(html).toContain("taskCodeVar");
    });
});
