import { type ChangeEvent, useReducer, useRef, useState } from "react"; import { gameReducer, initialGameState } from "#/reducers/gameReducer.ts"; import { buildPgnString, getHeaders } from "#/utils/pgnUtils.ts"; import { downloadString } from "#/utils/stringUtils.ts"; interface IPosition { ply: number; fen: string; } export const useChessGame = () => { const [gameState, gameDispatch] = useReducer(gameReducer, initialGameState); const [currentPosition, setCurrentPosition] = useState({ ply: 0, fen: "", }); const fileInputRef = useRef(null); const handlePlyChange = ({ ply, fen }: { ply: number; fen: string }) => { setCurrentPosition({ ply, fen }); }; const handleSavePgn = () => { const pgnString = buildPgnString(gameState); downloadString(pgnString, "game.pgn"); }; const handleSavePdf = () => { console.log("Save PDF"); }; const handleClearGame = () => { if (fileInputRef.current) { fileInputRef.current.value = ""; } gameDispatch({ type: "CLEAR_GAME", }); }; const handleLoadPgn = (e: ChangeEvent) => { e.preventDefault(); const selectedFile = e.target.files?.[0]; if (selectedFile?.name.endsWith(".pgn")) { const reader = new FileReader(); reader.onload = (event) => { const pgnData = event.target?.result; let pgnString = ""; if (pgnData) { if (typeof pgnData === "string") { pgnString = pgnData; } else { pgnString = new TextDecoder().decode(pgnData); } } if (pgnString) { const headers = { ...getHeaders(pgnString), title: "", subtitle: "", }; gameDispatch({ type: "SET_GAME", payload: { pgn: pgnString, headers: headers }, }); } else { e.target.files = null; handleClearGame(); } }; reader.readAsText(selectedFile); } else { handleClearGame(); } }; const handleToggleClock = () => { gameDispatch({ type: "TOGGLE_DIAGRAM_CLOCK", }); }; const handleToggleDiagram = () => { if (!gameState.pgn) return; const { ply, fen } = currentPosition; if (ply === 0) return; const exists = gameState.diagrams.some((d) => d.ply === ply); gameDispatch( exists ? { type: "DELETE_DIAGRAM", payload: { ply } } : { type: "ADD_DIAGRAM", payload: { ply, fen } }, ); }; return { gameState, fileInputRef, handleSavePgn, handleSavePdf, handleClearGame, handleLoadPgn, handleToggleClock, handlePlyChange, handleToggleDiagram, currentPosition, }; };