import {
	Accessor,
	createContext,
	createEffect,
	createResource,
	createSignal,
	For,
	onCleanup,
	Resource,
	ResourceReturn,
	Show,
	untrack,
} from "solid-js";
import {
	GameState,
	Action,
	vGameState,
	PlayerView,
} from "../../../server/src/games/simple";
import api from "../api";
import Hand from "./Hand";
import Pile from "./Pile";
import { ApiType } from "../fn";
import { createStore } from "solid-js/store";

export const GameContext = createContext<{
	view: Accessor<PlayerView | undefined>;
	submitAction: (action: Action) => Promise<any>;
}>();

const [playerProfiles, setPlayerProfiles] = createStore<
	Record<string, Resource<ApiType<typeof api.profile.get>>>
>({});

export default (props: { tableKey: string }) => {
	const [view, setView] = createSignal<PlayerView>();
	const [players, setPlayers] = createSignal<string[]>([]);

	createEffect(() => {
		players().forEach((player) => {
			if (!untrack(() => playerProfiles[player])) {
				const [playerProfile] = createResource(() =>
					api.profile
						.get({ query: { otherHumanKey: player } })
						.then((r) => r.data)
				);
				setPlayerProfiles((prev) => ({
					...prev,
					[player]: playerProfile,
				}));
			}
		});
	});

	const ws = api(props).subscribe;
	onCleanup(() => ws.close());
	ws.on("message", (evt) => {
		if (evt.data.players) {
			setPlayers(evt.data.players);
		}
		if (evt.data.view) {
			setView(evt.data.view);
		}
	});

	const submitAction = (action: Action) => api.simple(props).post({ action });

	const Lobby = () => {
		return (
			<div class="fixed tc mt-20 flex flex-col items-center">
				<button class="button p-1 m-10">Start Game!</button>
				<For each={players()}>
					{(player) => (
						<p style={{ "font-size": "2em" }}>
							{playerProfiles[player]?.()?.name}
						</p>
					)}
				</For>
			</div>
		);
	};
	return (
		<GameContext.Provider value={{ view, submitAction }}>
			<Show when={view() != undefined} fallback={<Lobby />}>
				<Pile
					count={view()!.deckCount}
					class="cursor-pointer fixed center"
					onClick={() => submitAction({ type: "draw" })}
				/>

				<Hand class="fixed bc" hand={view()!.myHand} />
			</Show>
		</GameContext.Provider>
	);
};
