import { css } from "@emotion/css";
import { Mathuscript, parseMathuscript } from "./parse";
import katex from "katex";
import { useCallback, useLayoutEffect, useMemo, useRef, useState } from "react";
import { MathText } from "./MathText";
import { characterData } from "./data";

type VisualState = {
	characters: {name: string, emotion: string, x: number}[],
	board: {text: string},
	dialog: {name: string | null, text: string},
}

const afterStep = (state: VisualState, step: Mathuscript[number]): VisualState => {
	const newState = structuredClone(state);
	const {characters, board, dialog} = newState;
	if (step.name === "board") {
		board.text = step.text;
	} else {
		let char = characters.find(c => c.name === step.name);
		if (!char) {
			char = {name: step.name, emotion: "default", x: 0.5};
			characters.push(char);
		}
		char.emotion = step.emotion ?? char.emotion;
		dialog.name = step.name;
		dialog.text = step.text;
	}
	console.log(newState);
	return newState;
}

const getCharData = (name: string | null) => {
	if (name && name in characterData) {
		return characterData[name as keyof typeof characterData];
	}
	return null;
}

export const MathuscriptPlayer = (props: { script: string }) => {
	const {script} = props;
	const parsedScript = useMemo(() => parseMathuscript(script), [script]);
	const [index, setIndex] = useState(0);
	const [visualState, setVisualState] = useState<VisualState>({characters: [], board: {text: ""}, dialog: {name: null, text: ""}});

	const doStep = useCallback(() => {
		const step = parsedScript[index];
		if (step) {
			console.log(step);
			setIndex(i => i+1);
			setVisualState(state => afterStep(state, step));
		} else {
			console.log("the end");
		}
	}, [index, parsedScript, setIndex, setVisualState]);

	const speakingChar = getCharData(visualState.dialog.name);

	return (
		<>
			<div className={css`
				width: 800px;
				height: 480px;
				border: 1px solid black;
				font-size: 16px;
				margin: auto;
				position: relative;
				background-image: url("/assets/background.png");
				background-size: 118%;
				background-position-x: center;
				background-position-y: bottom;
				overflow: hidden;
			`}>
				<div className={css`
					position: absolute;
					width: 58%;
					top: 7%;
					left: 21%;
					height: 64%;
					display: flex;
					align-items: center;
					justify-content: center;
					color: white;
					/* background-color: rgba(255, 0, 0, 0.3); */
					padding: 1em;
				`}>
					<div>
						<MathText>{visualState.board.text}</MathText>
					</div>
				</div>
				<div className={css`
					position: absolute;
					width: 100%;
					height: 100%;
					top: 0;
					left: 0;
				`}>
					{
						visualState.characters.map(c => {
							// TODO: make it change with emotion
							const char = getCharData(c.name);
							if (!char) {
								return null;
							}
							return <img
								className={css`
									position: absolute;
									left: -20%;
									height: 90%;
									bottom: 0;
								`}
								key={c.name}
								src={char.assets["default"]}
							/>
						})
					}
				</div>
				<div className={css`
					padding: 1em;
					display: flex;
					position: absolute;
					width: 100%;
					height: 25%;
					bottom: 0;
				`}>
					<div className={css`
						flex-basis: 0;
						flex-grow: 1;
						background-color: hsla(220, 50%, 40%, 0.85);
						border: 2px solid hsla(220, 30%, 60%, 0.85);
						border-radius: 0.25em;
						padding: 0.5em;
						color: white;
					`}>
						{
							speakingChar && <>
								<strong>{speakingChar.displayName}.</strong> <MathText>{visualState.dialog.text}</MathText>
							</>
						}
					</div>
				</div>
			</div>
			<button onClick={doStep}>Step</button>
		</>
	);
};