import { EditorSelection } from "@codemirror/state";
import { MantineProvider, Paper, v8CssVariablesResolver } from "@mantine/core";
import { setMarkdownEditorFocused } from "@src/lib/markdown/editor/decorations/editor-focus";
import { MarkdownEditor } from "@src/primitives/MarkdownEditor";
import { MANTINE_THEME } from "@src/theme/mantine";
import { describe, expect, it } from "vitest";
import { getEditorView, mountStory, nextFrame, sleep } from "../../_setup/e2e-helpers";

const DOC =
    "Regular paragraph line.\n\n![Some alt text](https://surrealdb.com/static/logo/light.svg)\n\nAnother paragraph.\n";

/** Left edge of a line's rendered text content (text nodes have no element box). */
function textLeft(line: HTMLElement): number {
    const range = document.createRange();
    range.selectNodeContents(line);
    return range.getBoundingClientRect().left;
}

describe("MarkdownEditor / media alignment", () => {
    it("aligns the image preview's left edge with regular text", async () => {
        mountStory(
            <MantineProvider
                theme={MANTINE_THEME}
                cssVariablesResolver={v8CssVariablesResolver}
                forceColorScheme="dark"
            >
                <Paper p="md">
                    <MarkdownEditor
                        mode="preview"
                        document={DOC}
                        autoFocus={false}
                    />
                </Paper>
            </MantineProvider>,
        );
        const view = await getEditorView();
        view.focus();
        view.dispatch({
            selection: EditorSelection.cursor(view.state.doc.length),
            effects: setMarkdownEditorFocused.of(true),
        });
        await sleep(200);
        await nextFrame();

        const para = Array.from(document.querySelectorAll<HTMLElement>(".cm-line")).find((l) =>
            (l.textContent ?? "").includes("Regular"),
        );
        const img = document.querySelector<HTMLElement>('[data-md-widget="ImageWidget"] img');
        expect(para).toBeTruthy();
        expect(img).toBeTruthy();

        const paraLeft = textLeft(para as HTMLElement);
        const imageLeft = (img as HTMLElement).getBoundingClientRect().left;
        // Within a pixel of the text inset (previously 6px to the left).
        expect(Math.abs(imageLeft - paraLeft)).toBeLessThanOrEqual(1.5);
    });
});
