import React, { useState } from "react";
import GameBoard from "./components/GameBoard";
import DiceSet from "./components/DiceSet";
import "./GamePage.scss";
import { buildBoard, PieceId } from "interface";
import { DieViewProps } from "./types/DieViewProps";
import { PlacePieceActionStack } from "./types/PlacePieceActionStack";

const GamePage = () => {
  const getRandomPieceId = () => {
    const randomId = Math.floor(Math.random() * Object.keys(PieceId).length);
    return Object.values(PieceId)[randomId];
  };

  const getRandomDiceSet: () => DieViewProps[] = () =>
    [1, 2, 3, 4].map(() => {
      return {
        pieceId: getRandomPieceId(),
        isSelected: false,
        isDisabled: false,
        isSpecial: false,
        rotation: 0,
      };
    });

  const [dice, setDice] = useState(getRandomDiceSet());
  const [specialDice, setSpecialDice] = useState(
    [
      PieceId.P03,
      PieceId.P08,
      PieceId.P13,
      PieceId.P14,
      PieceId.P15,
      PieceId.P19,
    ].map((pieceId) => {
      return {
        pieceId: pieceId,
        isSelected: false,
        isDisabled: false,
        isSpecial: true,
        rotation: 0,
      };
    }),
  );
  const [specialDieUsedInRound, setSpecialDieUsedInRound] = useState(false);

  const modifyDieState = (
    matcher: (die: DieViewProps) => boolean,
    newStateComputer: (die: DieViewProps) => Partial<DieViewProps>,
  ) => {
    setDice(
      dice.map((die) => {
        if (!matcher(die)) return die;
        return {
          ...die,
          ...newStateComputer(die),
        };
      }),
    );
    setSpecialDice(
      specialDice.map((die) => {
        if (!matcher(die)) return die;
        return {
          ...die,
          ...newStateComputer(die),
        };
      }),
    );
  };

  const fetchDie = (matcher: (die: DieViewProps) => boolean) => {
    return dice.concat(specialDice).find((die) => matcher(die));
  };

  const [board, setBoard] = useState(buildBoard());
  const [id, setId] = useState(1);
  const refreshBoardRender = () => {
    setBoard(board);
    setId(id + 1);
  };

  const [placePieceActionStack, setPlacePieceActionStack] = useState(
    new PlacePieceActionStack(),
  );
  const resetBoard = () => {
    placePieceActionStack.resetActions(board);
    setBoard(board);
    modifyDieState(
      () => true,
      () => {
        return { isSelected: false, isDisabled: false };
      },
    );
    setId(id + 1);
  };
  const commitBoard = () => {
    if (dice.some((die) => !die.isDisabled)) return;
    placePieceActionStack.commitActions();
    setDice(getRandomDiceSet());
    setSpecialDieUsedInRound(false);
  };

  return (
    <React.Fragment>
      <h1>Game Page Title</h1>
      <div className="game-panel" id={id.toString()}>
        <GameBoard
          modifyDieState={modifyDieState}
          fetchDie={fetchDie}
          setSpecialDieUsedInRound={setSpecialDieUsedInRound}
          refreshBoardRender={refreshBoardRender}
          board={board}
          placePieceActionStack={placePieceActionStack}
          setPlacePieceActionStack={setPlacePieceActionStack}
        />
        <div className="right-panel">
          <DiceSet
            dice={dice}
            specialDice={specialDice}
            modifyDieState={modifyDieState}
            specialDieUsedInRound={specialDieUsedInRound}
            resetBoard={resetBoard}
            commitBoard={commitBoard}
          />
        </div>
      </div>
    </React.Fragment>
  );
};

export default GamePage;
