import { css } from "@emotion/css";
import { PicoCart, PicoPlayerHandle, makePicoConsole } from "./renderCart";
import { ForwardedRef, forwardRef, useCallback, useEffect, useImperativeHandle, useRef, useState } from "react";

type Pico8ConsoleImperatives = {
	getPicoConsoleHandle(): PicoPlayerHandle | null;
}

export const Pico8Console = forwardRef((props: { carts: PicoCart[] }, forwardedRef: ForwardedRef<Pico8ConsoleImperatives>) => {
	const {carts} = props;
	const [playing, setPlaying] = useState(false);
	const playingRef = useRef(false);
	const ref = useRef<HTMLDivElement>(null);
	const listeners = useRef<Partial<{
		keydown: null | ((ev: KeyboardEvent) => void)
	}>>({});
	const [handle, setHandle] = useState<PicoPlayerHandle | null>(null);
	const attachConsole = useCallback(async () => {
		const picoConsole = await makePicoConsole({
			carts,
		});
		const codoTextarea: HTMLTextAreaElement = (picoConsole.rawModule as any).codo_textarea;
		picoConsole.canvas.addEventListener('click', () => {
			codoTextarea.focus();
			codoTextarea.select();
		})
		if (ref.current) {
			ref.current.appendChild(picoConsole.canvas);
			ref.current.appendChild(codoTextarea);
		}
		setHandle(picoConsole);
		listeners.current.keydown = function (event) {
			console.log("keydown", event.key);
			if (!playingRef.current) {
				return;
			}
			console.log(picoConsole.state);
			if (picoConsole.state.hasFocus) {
				console.log("hasFocus");
				// block only cursors, M R P, tab
				if (["ArrowUp", "ArrowDown", "ArrowLeft", "ArrowRight", "M", "R", "P", "m", "r", "p", "Tab"].includes(event.key)) {
						console.log("preventDefault");
						event.preventDefault();
				}
			}
		};
		document.addEventListener('keydown',
			listeners.current.keydown,
			{passive: false}
		);
	}, [carts]);
	useImperativeHandle(forwardedRef, () => ({
		getPicoConsoleHandle() {
			return handle;
		}
	}), [handle]);
	useEffect(() => {
		if (playing && playingRef.current) {
			attachConsole();
			return () => {
				playingRef.current = false;
				if (ref.current) {
					ref.current.innerHTML = "";
				}
				if (listeners.current.keydown) {
					document.removeEventListener("keydown", listeners.current.keydown);
					listeners.current.keydown = null;
				}
			}
		}
	}, [playing, attachConsole]);
	if (!playing) {
		return (
			<div
				ref={ref}
				className={css`
					width: 100%;
					height: 100%;
					display: flex;
					align-items: center;
					justify-content: center;
					aspect-ratio: 1;
					background-color: black;
					color: white;
					cursor: pointer;
				`}
				onClick={() => {playingRef.current = true; setPlaying(true)}}
			>
				Play!
			</div>
		)
	}
	return (
		<div ref={ref} className={css`
			width: 100%;
			height: 100%;
			display: flex;
			align-items: center;
			justify-content: center;

			& > canvas {
				width: 100%;
				height: 100%;
			}
		`}></div>
	);
});
