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

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

export type Pico8ConsoleProps = {
	carts: PicoCart[],
	// onGpioChange?(gpio: number[]): void,
}

// const noop = () => {};

export const Pico8Console = forwardRef((props: Pico8ConsoleProps, forwardedRef: ForwardedRef<Pico8ConsoleImperatives>) => {
	const {
		carts,
		// onGpioChange = noop
	} = props;
	const [playing, setPlaying] = useState(false);
	const ref = useRef<HTMLDivElement>(null);
	const [handle, setHandle] = useState<PicoPlayerHandle | null>(null);
	const attachConsole = useCallback(async () => {
		const picoConsole = await makePicoConsole({
			carts,
		});
		picoConsole.canvas.tabIndex=0;
		if (ref.current) {
			ref.current.appendChild(picoConsole.canvas);

			// Set the width and height because pico8 adds them as properties on chrome-based browsers
			picoConsole.canvas.style.width = "";
			picoConsole.canvas.style.height = "";

			picoConsole.canvas.focus();
		}
		setHandle(picoConsole);
		// picoConsole.gpio.subscribe(onGpioChange);
		picoConsole.canvas.addEventListener('keydown',(event) => {
			if (["ArrowUp", "ArrowDown", "ArrowLeft", "ArrowRight"].includes(event.key)) {
				event.preventDefault();
			}
		}, {passive: false});
		picoConsole.canvas.addEventListener('click', () => {
			picoConsole.canvas.focus();
		})
	}, [carts]);
	useImperativeHandle(forwardedRef, () => ({
		getPicoConsoleHandle() {
			return handle;
		}
	}), [handle]);
	useEffect(() => {
		if (playing) {
			attachConsole();
			return () => {
				if (ref.current) {
					ref.current.innerHTML = "";
				}
			}
		}
	}, [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;
				`}
				tabIndex={0}
				onClick={() => {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>
	);
});
