'use client';

import { createContext, useContext, useEffect, useState, ReactNode } from 'react';
import useSocket from '@/hooks/useSocket';
import type { GameUpdate, Tilt } from '@/types';

const AppContext = createContext<AppContext | undefined>(undefined);

const gameStart: GameUpdate = {
	dmID: '',
	spectatorID: '',
	cards: [],
	settings: {
		positionBack: false,
		positionFront: false,
		prophecy: false,
		notes: false,
		cardStyle: 'color',
	},
	tilts: Array.from({ length: 5 }, () => []),
};

export interface AppContext {
	gameData: GameUpdate;
	noGame: boolean;
	tilt: Tilt[];
	selectCardIndex: number;
	flipCard: (cardIndex: number) => void;
	handleSettings: (gameData: GameUpdate) => void;
	redraw: (cardIndex: number) => void;
	select: (cardID: string) => void;
	setGameID: (gameID: string) => void;
	setSelectCardIndex: (cardIndex: number) => void;
	setTilt: (tilt: Tilt[]) => void;
}

export function AppProvider({ children }: { children: ReactNode }) {
	const [gameData, setGameData] = useState<GameUpdate>(gameStart);
	const [gameID, setGameID] = useState('');
	const [noGame, setNoGame] = useState(false);
	const [selectCardIndex, setSelectCardIndex] = useState(-1);
	const [tilt, setTilt] = useState<Tilt[]>([]);

	const { flipCard, redraw, select, handleSettings, emitTilt } = useSocket({
		gameID,
		setGameData,
		setNoGame,
	});

	useEffect(() => {
		const cardIndex = tilt.findIndex((tilt) => !!tilt);

		if (tilt[cardIndex]) {
			emitTilt(cardIndex, tilt[cardIndex]);
		}
	}, [tilt]);

	const handleSelect = (cardID: string) => {
		setSelectCardIndex(-1);

		select(selectCardIndex, cardID);
	};

	const appInterface = {
		gameData,
		noGame,
		tilt,
		selectCardIndex,
		flipCard,
		handleSettings,
		redraw,
		select: handleSelect,
		setGameID,
		setSelectCardIndex,
		setTilt,
	};

	return <AppContext.Provider value={appInterface}>{children}</AppContext.Provider>;
}

export function useAppContext(): AppContext {
	const context = useContext(AppContext);
	if (!context) throw new Error('useAppContext must be used within AppProvider');
	return context;
}
