const tictactoeBoard = (function() {

    let gameBoard = new Array(["", "", ""], ["", "", ""], ["", "", ""]);

    const getGameBoard = () => gameBoard;
    // const printGameBoard = () => console.log(gameBoard[0] + "\n" + gameBoard[1] + "\n" + gameBoard[2]);

    const resetGameBoard = () => {
        gameBoard.forEach(item => {
            item[0] = '';
            item[1] = '';
            item[2] = '';
        })
    }

    const posititionAvailable = (position) => {
        switch (position) {
            case 1:
                return isEmpty(gameBoard[0][0]);
            case 2:
                return isEmpty(gameBoard[0][1]);
            case 3:
                return isEmpty(gameBoard[0][2]);
            case 4:
                return isEmpty(gameBoard[1][0]);
            case 5:
                return isEmpty(gameBoard[1][1]);
            case 6:
                return isEmpty(gameBoard[1][2]);
            case 7:
                return isEmpty(gameBoard[2][0]);
            case 8:
                return isEmpty(gameBoard[2][1]);
            case 9:
                return isEmpty(gameBoard[2][2]);
            default:
                Alert('Must enter a number 1 - 9');
                break;
        }
    }

    const isEmpty = position => position === "";

    const placeOnBoard = (position, marker) => {
        // places marker on the gameboard
        marker = marker.getValue(); // get value from object 

        switch (position) {
            case 1:
                gameBoard[0][0] = marker;
                break;
            case 2:
                gameBoard[0][1] = marker;
                break;
            case 3:
                gameBoard[0][2] = marker;
                break;
            case 4:
                gameBoard[1][0] = marker;
                break;
            case 5:
                gameBoard[1][1] = marker;
                break;
            case 6:
                gameBoard[1][2] = marker;
                break;
            case 7:
                gameBoard[2][0] = marker;
                break;
            case 8:
                gameBoard[2][1] = marker;
                break;
            case 9:
                gameBoard[2][2] = marker;
                break;
            default:
                break;
        }
    }

    return {
        resetGameBoard,
        // printGameBoard,
        getGameBoard,
        placeOnBoard,
        posititionAvailable
    };
})();


const playerInfo = (function() {
    class Player {
        constructor(name, piece) {
            this.piece = piece;
            this.name = name;
        }
    }

    const player = (name, piece) => {
        return new Player(name, piece);
    };

    return { player }
})();


function block() {
    value = "-";
    const addToken = player => {
        // player is a player info object
        value = player.piece;
    };

    const getValue = () => value;

    return {
        addToken,
        getValue
    };
};

const gameController = (() => {
    // Controls the overall flow of the game
    let players = [
        playerInfo.player('Player 1', 'X'),
        playerInfo.player('Player 2', 'O')
    ]

    let gameOver;
    let xTurn = true; // True = X's turn, False = O's turn
    let round = 0; // 9 Total Rounds for Tic Tac Toe

    const resetGame = () => {
        round = 0;
        xTurn = true;
        gameOver = false;
        tictactoeBoard.resetGameBoard();
    }

    const gameStatus = () => gameOver;
    const gameRound = () => round;

    const switchPlayerTurn = () => {
        xTurn = !xTurn;
    }

    const playRound = position => {
        let marker = new block()
        let positionOpen = tictactoeBoard.posititionAvailable(position);

        if (round < 10 && positionOpen) {

            let player = xTurn ? players[0] : players[1];
            marker.addToken(player);
            tictactoeBoard.placeOnBoard(position, marker); // position on board 

            // Check for Winner
            gameOver = evalGameOutcome(tictactoeBoard.getGameBoard());

            if (gameOver) {
                console.log(`${player.name}: ${player.piece} won!`)
                return
            } 
            switchPlayerTurn();

        } else {
            return
        }
        round += 1;
    }

    const evalGameOutcome = gameBoard => {
        // create a new array of the vertical indexes in the game board
        let vertArray = [];
        gameBoard.forEach((_, index) => vertArray.push(gameBoard.map(e => e[index])));

        // create an array of diagnal pieces
        let diagArray = [
            [gameBoard[0][0], gameBoard[1][1], gameBoard[2][2]],
            [gameBoard[0][2], gameBoard[1][1], gameBoard[2][0]]
        ];

        let checkGameBoard = [gameBoard, vertArray, diagArray]; 
        for (i = 0; i < 3; i++) {
            let outcome = _evalGameOutcome(checkGameBoard[i]);
            if (outcome) {
                return true;
            };
        };
        return false;
    };

    const _evalGameOutcome = arr => {
        // Checks if array values are equal to determine winner
        let isWinner = checkArr => checkArr.reduce(function(a, b) { return a === b ? a : false; });

        const outcome = arr.find(element => {
            let result = isWinner(element);
            if (result != false) {
                return true;
            } else {
                return false;
            }
        });
        return outcome;
    };

    return { playRound, resetGame, gameStatus, gameRound }
})();


const screenController = (() => {
    const contentDiv = document.querySelector('.content')
    const gameDiv = document.querySelector('.game-area');
    const gameStatus = document.querySelector('.game-status')
    const game = tictactoeBoard.getGameBoard();
    const resetButton = document.createElement('button');

    resetButton.classList.add(['btn']);
    resetButton.textContent = 'New Game';
    contentDiv.appendChild(resetButton);

    const updateScreen = () => {
        status()
        displayBoard();
    }

    const status = () => {
        let pTags = gameStatus.querySelectorAll('p');
        if (pTags) pTags.forEach(e => e.remove());

        let message = document.createElement('p');
        let gameOn = gameController.gameStatus() ? "Play again?" : "";
        let round = gameController.gameRound();
        
        if (round <= 9 && gameOn) {
            message.textContent = gameOn;
        } else if (round >= 9 && !gameOn) {
            message.textContent = "Draw, play again?"; 
        }

        gameStatus.appendChild(message);

    }


    const displayBoard = () => {
        // Check if someone won the game

        let count = 0; // This is for the data blocks
        gameDiv.querySelectorAll('.block').forEach(e => e.remove());
        game.forEach((e) => {
            e.forEach((element) => {
            count += 1;
            const block = document.createElement('div');
            block.classList.add('block');
            block.setAttribute('data-block', count);
            block.textContent = element;
            block.addEventListener('click', clickHandlerBoard);
            gameDiv.appendChild(block);
            });
        });
    }



    function clickHandlerBoard(e) {
            const selectedBlock = e.target.dataset.block;
            const empty = e.target.textContent;
            const gameStatus = gameController.gameStatus();

            if (!selectedBlock || empty !== "" || gameStatus) return;

            gameController.playRound(Number(selectedBlock));
            updateScreen();
    };

    function clickResetButton() {
        gameController.resetGame();
        status();
        updateScreen();
    }

    resetButton.addEventListener('click', clickResetButton);


    // Initial Load
    updateScreen();
})();