import { Bank, MancalaGame, Pit } from "mancala.js";
import * as React from "react";
import { FunctionComponent, useState } from "react";

type Theme = {
  background: string;
  boardColor: string;
  boardColorWhenPlayerTurn: string;
  storeColor: string;
  storeColorWhenPlayerTurn: string;
  holeColor: string;
  ballColor: string;
  ballLightColor: string;
  holeAnimateColor: string;
};

const theme: Theme = {
  background: "#EEEEEE",
  boardColor: "#4D606E",
  boardColorWhenPlayerTurn: "#84b8a6",
  storeColor: "#3FBAC2",
  storeColorWhenPlayerTurn: "#6cab94",
  holeColor: "#D3D4D8",
  ballColor: "#393E46",
  ballLightColor: "#393E46",
  holeAnimateColor: "#afb3a4",
};

const BallView: FunctionComponent<{ color: string }> = ({ color }) => {
  return (
    <div
      style={{
        background: color,
        margin: "1px",
        width: "1vw",
        height: "1vw",
        borderRadius: "10vw",
      }}
    ></div>
  );
};

function range(size: number) {
  var ans = [];
  for (let i = 0; i < size; i++) {
    ans.push(i);
  }
  return ans;
}

const PitContainer: FunctionComponent<{
  pit: Pit;
  isAnimating: boolean;
  onClick: () => void;
}> = ({ pit, isAnimating, onClick }) => {
  if (isAnimating) {
    pit.stoneCount += 1;
  }
  return (
    <>
      <HoleView
        hole={pit}
        color={isAnimating ? theme.holeAnimateColor : theme.holeColor}
        stoneColor={isAnimating ? theme.ballLightColor : theme.ballColor}
        onClick={onClick}
      />
    </>
  );
};

const HoleView: FunctionComponent<{
  hole: Pit;
  color: string;
  stoneColor: string;
  onClick: () => void;
}> = ({ hole, color, stoneColor, onClick }) => {
  const balls = [...range(hole.stoneCount)].map((i) => (
    <BallView color={stoneColor} />
  ));

  return (
    <div
      onClick={onClick}
      style={{
        background: color,
        margin: "5px",
        padding: "5px",
        borderRadius: "10vw",
        display: "flex",
        alignItems: "center",
        alignContent: "center",
        justifyContent: "center",
        justifyItems: "center",
        flexWrap: "wrap",
      }}
    >
      {balls}
    </div>
  );
};

const StoreView: FunctionComponent<{
  store: Bank;
  color: string;
  stoneColor: string;
  gridColumn: string;
  gridRow: string;
}> = ({ store, color, stoneColor, gridColumn, gridRow }) => {
  const balls = [...range(store.stoneCount)].map((i) => (
    <BallView color={stoneColor} />
  ));
  return (
    <div
      style={{
        gridColumn: gridColumn,
        gridRow: gridRow,
        background: color,
        margin: "5px",
        borderRadius: "10vw",
        display: "flex",
        alignItems: "center",
        justifyContent: "center",
        alignContent: "center",
        flexWrap: "wrap",
      }}
    >
      {balls}
    </div>
  );
};

const BoardView: FunctionComponent<{
  game?: MancalaGame;
  userKey: string;
  onHoleSelect: (index: number, hole: Pit) => void;
  animationPitIndex: number;
}> = ({ game, userKey, onHoleSelect, animationPitIndex }) => {
  const player1Pits = game?.board.player1Pits.map((pit) => {
    const isAnimating = pit.index === animationPitIndex;
    return (
      <PitContainer
        pit={pit}
        isAnimating={isAnimating}
        onClick={() => {
          if (game.turnPlayerId === game.player1Id)
            onHoleSelect(game.board.player1Pits.indexOf(pit), pit);
        }}
      />
    );
  });

  const player2Pits = game!!.board.player2Pits.map((pit) => {
    const isAnimating = pit.index === animationPitIndex;
    return (
      <PitContainer
        pit={pit}
        isAnimating={isAnimating}
        onClick={() => {
          if (game.turnPlayerId === game.player2Id)
            onHoleSelect(game.board.player2Pits.indexOf(pit), pit);
        }}
      />
    );
  });

  const isUserTurn = game.checkIsPlayerTurn(userKey);

  const animatingPlayer1Bank =
    game.board.player1Bank.index === animationPitIndex;
  const animatingPlayer2Bank =
    game.board.player2Bank.index === animationPitIndex;

  const storeColorPlayer1 = animatingPlayer1Bank
    ? theme.holeAnimateColor
    : isUserTurn
    ? theme.storeColor
    : theme.storeColorWhenPlayerTurn;

  const storeStoneColorPlayer1 = animatingPlayer1Bank
    ? theme.ballLightColor
    : theme.ballColor;

  const storeColorPlayer2 = animatingPlayer2Bank
    ? theme.holeAnimateColor
    : isUserTurn
    ? theme.storeColor
    : theme.storeColorWhenPlayerTurn;

  const storeStoneColorPlayer2 = animatingPlayer2Bank
    ? theme.ballLightColor
    : theme.ballColor;
  return (
    <div
      style={{
        margin: "10px",
        padding: "20px",
        display: "grid",
        gridTemplateColumns: "repeat(8, 11vw)",
        gridTemplateRows: "repeat(2, 11vw)",
        borderRadius: "3vw",
        background: isUserTurn
          ? theme.boardColor
          : theme.boardColorWhenPlayerTurn,
      }}
    >
      {userKey === game.player2Id ? (
        <>
          <StoreView
            store={game!!.board.player1Bank}
            color={storeColorPlayer1}
            stoneColor={storeStoneColorPlayer1}
            gridColumn="1 / 2"
            gridRow="1 / 3"
          />
          <StoreView
            store={game!!.board.player2Bank}
            color={storeColorPlayer2}
            stoneColor={storeStoneColorPlayer2}
            gridColumn="8 / 9"
            gridRow="1 / 3"
          />
          {player1Pits.reverse()}
          {player2Pits}
        </>
      ) : (
        <>
          <StoreView
            store={game!!.board.player2Bank}
            color={storeColorPlayer2}
            stoneColor={storeStoneColorPlayer2}
            gridColumn="1 / 2"
            gridRow="1 / 3"
          />
          <StoreView
            store={game!!.board.player1Bank}
            color={storeColorPlayer1}
            stoneColor={storeStoneColorPlayer1}
            gridColumn="8 / 9"
            gridRow="1 / 3"
          />
          {player2Pits.reverse()}
          {player1Pits}
        </>
      )}
    </div>
  );
};

export default BoardView;
