import React, { useState } from 'react';
import ReactDOM from 'react-dom';

const rowStyle = {
  display: 'flex'
}

const squareStyle = {
  'width':'60px',
  'height':'60px',
  'backgroundColor': '#ddd',
  'margin': '4px',
  'display': 'flex',
  'justifyContent': 'center',
  'alignItems': 'center',
  'fontSize': '20px',
  'color': 'white'
}

const boardStyle = {
  'backgroundColor': '#eee',
  'width': '208px',
  'alignItems': 'center',
  'justifyContent': 'center',
  'display': 'flex',
  'flexDirection': 'column',
  'border': '3px #eee solid'
}

const containerStyle = {
  'display': 'flex',
  'alignItems': 'center',
  'flexDirection': 'column'
}

const instructionsStyle = {
  'marginTop': '5px',
  'marginBottom': '5px',
  'fontWeight': 'bold',
  'fontSize': '16px',
}

const buttonStyle = {
  'marginTop': '15px',
  'marginBottom': '16px',
  'width': '80px',
  'height': '40px',
  'backgroundColor': '#8acaca',
  'color': 'white',
  'fontSize': '16px',
}

class Square extends React.Component {
  constructor(props){
    super(props);
  }
  render() {
    return (
      <div onClick={() => this.props.mark()}
        className="square"
        style={squareStyle}>
        {this.props.text()}
      </div>
    );
  }
}

class Board extends React.Component {

  constructor(props){
    super(props);
    this.nextPlayer = this.nextPlayer.bind(this);
    this.defaultTiles = this.defaultTiles.bind(this);

    this.state = {
      currentPlayer: 'X',
      clickCount: 0,
      winner: 'None',
      gameEnded: false,
      tiles: this.defaultTiles()
    };
    
  }

  defaultTiles = () => {
    let row = 3;
    let col = 3;
    let tiles= new Array(row);
    for(let j =0; j<row; j++){
      tiles[j] = new Array(col);
    }
    return tiles;
  };

  markTile = (i,j) => {  
    let {tiles, gameEnded, currentPlayer} = this.state;
    if(tiles[i][j] == null && !gameEnded){
      tiles[i][j] = currentPlayer; 
      let {winner, gameEnded, clickCount} = this.evalBoard();
      this.setState({
        currentPlayer: this.nextPlayer(),
        tiles,
        winner, 
        clickCount,
        gameEnded
      });
    }
  };

  evalBoard =  () => {
    let winner = 'None';
    let gameEnded = false;
    let {tiles, clickCount} = this.state;
    let playerArr = ['X', 'O'];
    clickCount = clickCount+1;

    // check the 8 conditions for game completion 
    if((tiles[0][2] == tiles[1][2]) && (tiles[0][2] == tiles[2][2]) && playerArr.indexOf(tiles[0][2]) > -1){
      winner = tiles[0][2];
      gameEnded = true;
    }else if((tiles[0][0] == tiles[0][1]) && (tiles[0][0] == tiles[0][2]) && playerArr.indexOf(tiles[0][0]) > -1){
      winner = tiles[0][0];
      gameEnded = true;
    }else if((tiles[0][0] == tiles[1][1]) && (tiles[0][0] == tiles[2][2]) && playerArr.indexOf(tiles[0][0]) > -1){
      winner = tiles[0][0];
      gameEnded = true;
    }else if((tiles[0][0] == tiles[1][0]) && (tiles[0][0] == tiles[2][0]) && playerArr.indexOf(tiles[0][0]) > -1){      
      winner = tiles[0][0];
      gameEnded = true;
    }else if((tiles[2][0] == tiles[2][1]) && (tiles[2][0] == tiles[2][2]) && playerArr.indexOf(tiles[2][0]) > -1){      
      winner = tiles[2][0];
      gameEnded = true;
    }else if((tiles[2][0] == tiles[1][1]) && (tiles[2][0] == tiles[0][2]) && playerArr.indexOf(tiles[2][0]) > -1){
      winner = tiles[2][0];
      gameEnded = true;
    }else if((tiles[1][0] == tiles[1][1]) && (tiles[1][0] == tiles[1][2]) && playerArr.indexOf(tiles[1][0]) > -1){
      winner = tiles[1][0];
      gameEnded = true;
    }else if((tiles[0][1] == tiles[1][1]) && (tiles[0][1] == tiles[2][1]) && playerArr.indexOf(tiles[0][1]) > -1){
      winner = tiles[0][1];
      gameEnded = true;
    }else if(clickCount == 9){
      gameEnded = true;
      winner = 'None';
    }

    return {winner, gameEnded, clickCount}
  }
  
  nextPlayer = () => {
   let currentPlayer = this.state.currentPlayer;   
    let playSwitch = {
      'X': 'O',
      'O': 'X' 
    };
    return playSwitch[currentPlayer];
  };

  tileValAt = (i, j) => {
     return this.state.tiles[i][j];
  };

  resetGame = () => {
    let val = {
      currentPlayer: 'X',
      winner: 'None',
      gameEnded: false,
      clickCount: 0,
      tiles: this.defaultTiles()
    };

    this.setState(val);
  }

  render() {
    let {currentPlayer, winner, gameEnded } = this.state;
    return (
      <div style={containerStyle} className="gameBoard">
        {!gameEnded ?<div id="statusArea" className="status" style={instructionsStyle}>Next player: <span>{ currentPlayer }</span></div> : null}
        {winner && gameEnded ? <div id="winnerArea" className="winner" style={instructionsStyle}>Winner: <span>{ winner }</span></div> : null}
        <button onClick={()=> this.resetGame()} style={buttonStyle}>Reset</button>
        <div style={boardStyle}> 
            <div className="board-row" style={rowStyle}>
              <Square mark={() => this.markTile(0,0)} text={() => this.tileValAt(0,0)}/>
              <Square mark={() => this.markTile(0,1)} text={() => this.tileValAt(0,1)}/>
              <Square mark={() => this.markTile(0,2)} text={() => this.tileValAt(0,2)}/>
            </div>


            <div className="board-row" style={rowStyle}>
              <Square mark={() => this.markTile(1,0)} text={() => this.tileValAt(1,0)}/>
              <Square mark={() => this.markTile(1,1)} text={() => this.tileValAt(1,1)}/>
              <Square mark={() => this.markTile(1,2)} text={() => this.tileValAt(1,2)}/>
            </div>



            <div className="board-row" style={rowStyle}>
              <Square mark={() => this.markTile(2,0)} text={() => this.tileValAt(2,0)}/>
              <Square mark={() => this.markTile(2,1)} text={() => this.tileValAt(2,1)}/>
              <Square mark={() => this.markTile(2,2)} text={() => this.tileValAt(2,2)}/>
            </div>


        </div>
      </div>
    );
  }
}

class Game extends React.Component {
  render() {
    return (
      <div className="game">
        <div className="game-board">
          <Board />
        </div>
      </div>
    );
  }
}

ReactDOM.render(
  <Game />,
  document.getElementById('root')
);