import { describe, expect, mock, test } from "bun:test";
import {
	createTextareaKeydownEvent,
	registerAIToolbarMarkupHooks,
	renderToolbarBoundary,
} from "./helpers/ai-toolbar-test-helpers";

registerAIToolbarMarkupHooks();

describe("AI toolbar keyboard shortcuts", () => {
	test("Ctrl+Enter triggers AI generation when the prompt has content", async () => {
		const onAiCreate = mock();

		const { textareaProps } = await renderToolbarBoundary({
			aiPrompt: "Draft a kickoff",
			onAiCreate,
		});
		const event = createTextareaKeydownEvent({ ctrlKey: true });

		textareaProps.onKeyDown?.(event);

		expect(event.preventDefault).toHaveBeenCalledTimes(1);
		expect(onAiCreate).toHaveBeenCalledTimes(1);
	});

	test("Cmd+Enter triggers AI generation when images are attached", async () => {
		const onAiCreate = mock();

		const { textareaProps } = await renderToolbarBoundary({
			imagePreviews: ["blob:first"],
			onAiCreate,
		});
		const event = createTextareaKeydownEvent({ metaKey: true });

		textareaProps.onKeyDown?.(event);

		expect(event.preventDefault).toHaveBeenCalledTimes(1);
		expect(onAiCreate).toHaveBeenCalledTimes(1);
	});

	test("Mod+Enter ignores extra modifiers so Shift+Ctrl+Enter does not generate", async () => {
		const onAiCreate = mock();

		const { textareaProps } = await renderToolbarBoundary({
			aiPrompt: "Draft a kickoff",
			onAiCreate,
		});
		const event = createTextareaKeydownEvent({
			ctrlKey: true,
			shiftKey: true,
		});

		textareaProps.onKeyDown?.(event);

		expect(event.preventDefault).not.toHaveBeenCalled();
		expect(onAiCreate).not.toHaveBeenCalled();
	});

	test("Mod+Enter ignores combined Ctrl+Meta modifiers", async () => {
		const onAiCreate = mock();

		const { textareaProps } = await renderToolbarBoundary({
			aiPrompt: "Draft a kickoff",
			onAiCreate,
		});
		const event = createTextareaKeydownEvent({
			ctrlKey: true,
			metaKey: true,
		});

		textareaProps.onKeyDown?.(event);

		expect(event.preventDefault).not.toHaveBeenCalled();
		expect(onAiCreate).not.toHaveBeenCalled();
	});

	test("Mod+Enter ignores Alt-modified submissions", async () => {
		const onAiCreate = mock();

		const { textareaProps } = await renderToolbarBoundary({
			aiPrompt: "Draft a kickoff",
			onAiCreate,
		});
		const event = createTextareaKeydownEvent({
			ctrlKey: true,
			altKey: true,
		});

		textareaProps.onKeyDown?.(event);

		expect(event.preventDefault).not.toHaveBeenCalled();
		expect(onAiCreate).not.toHaveBeenCalled();
	});

	test("Mod+Enter does not trigger AI generation while loading", async () => {
		const onAiCreate = mock();

		const { textareaProps } = await renderToolbarBoundary({
			aiPrompt: "Draft a kickoff",
			aiLoading: true,
			onAiCreate,
		});
		const event = createTextareaKeydownEvent({ ctrlKey: true });

		textareaProps.onKeyDown?.(event);

		expect(event.preventDefault).not.toHaveBeenCalled();
		expect(onAiCreate).not.toHaveBeenCalled();
	});

	test("Shift+Mod+A opens the image picker when the composer is idle", async () => {
		const { textareaProps, imageTriggerOpen } = await renderToolbarBoundary();
		const ctrlEvent = createTextareaKeydownEvent({
			key: "A",
			ctrlKey: true,
			shiftKey: true,
		});

		textareaProps.onKeyDown?.(ctrlEvent);

		expect(ctrlEvent.preventDefault).toHaveBeenCalledTimes(1);
		expect(imageTriggerOpen).toHaveBeenCalledTimes(1);
	});

	test("Mod+A without Shift does not open the image picker", async () => {
		const { textareaProps, imageTriggerOpen } = await renderToolbarBoundary();
		const event = createTextareaKeydownEvent({
			key: "A",
			ctrlKey: true,
		});

		textareaProps.onKeyDown?.(event);

		expect(event.preventDefault).not.toHaveBeenCalled();
		expect(imageTriggerOpen).not.toHaveBeenCalled();
	});

	test("Shift+Cmd+A also opens the image picker when the composer is idle", async () => {
		const { textareaProps, imageTriggerOpen } = await renderToolbarBoundary();
		const metaEvent = createTextareaKeydownEvent({
			key: "A",
			metaKey: true,
			shiftKey: true,
		});

		textareaProps.onKeyDown?.(metaEvent);

		expect(metaEvent.preventDefault).toHaveBeenCalledTimes(1);
		expect(imageTriggerOpen).toHaveBeenCalledTimes(1);
	});

	test("Shift+Mod+A ignores Alt-modified submissions", async () => {
		const { textareaProps, imageTriggerOpen } = await renderToolbarBoundary();
		const event = createTextareaKeydownEvent({
			key: "A",
			ctrlKey: true,
			shiftKey: true,
			altKey: true,
		});

		textareaProps.onKeyDown?.(event);

		expect(event.preventDefault).not.toHaveBeenCalled();
		expect(imageTriggerOpen).not.toHaveBeenCalled();
	});

	test("Shift+Mod+A ignores combined Ctrl+Meta modifiers", async () => {
		const { textareaProps, imageTriggerOpen } = await renderToolbarBoundary();
		const event = createTextareaKeydownEvent({
			key: "A",
			ctrlKey: true,
			metaKey: true,
			shiftKey: true,
		});

		textareaProps.onKeyDown?.(event);

		expect(event.preventDefault).not.toHaveBeenCalled();
		expect(imageTriggerOpen).not.toHaveBeenCalled();
	});

	test("Shift+Mod+A stays disabled while generation is in progress", async () => {
		const { textareaProps, imageTriggerOpen } = await renderToolbarBoundary({
			aiLoading: true,
		});
		const ctrlEvent = createTextareaKeydownEvent({
			key: "A",
			ctrlKey: true,
			shiftKey: true,
		});

		textareaProps.onKeyDown?.(ctrlEvent);

		expect(ctrlEvent.preventDefault).not.toHaveBeenCalled();
		expect(imageTriggerOpen).not.toHaveBeenCalled();
	});

	test("Escape clears the prompt when the textarea has content", async () => {
		const setAiPrompt = mock();

		const { textareaProps } = await renderToolbarBoundary({
			aiPrompt: "Draft a kickoff",
			setAiPrompt,
		});
		const event = createTextareaKeydownEvent({ key: "Escape" });

		textareaProps.onKeyDown?.(event);

		expect(event.preventDefault).toHaveBeenCalledTimes(1);
		expect(setAiPrompt).toHaveBeenCalledTimes(1);
		expect(setAiPrompt).toHaveBeenCalledWith("");
	});
});
