const routine = require('./routine')

const emptyBoard = [
  [' ', ' ', ' ', ' ', ' ', ' ', ' '],
  [' ', ' ', ' ', ' ', ' ', ' ', ' '],
  [' ', ' ', ' ', ' ', ' ', ' ', ' '],
  [' ', ' ', ' ', ' ', ' ', ' ', ' '],
  [' ', ' ', ' ', ' ', ' ', ' ', ' '],
  [' ', ' ', ' ', ' ', ' ', ' ', ' ']
]

const textFromBoard = board => {
  const makeRow = r => `  |${r[0]}|${r[1]}|${r[2]}|${r[3]}|${r[4]}|${r[5]}|${r[6]}|`
  return board.map(makeRow).join('\n') + '\n' +
      ' -----------------\n' +
      '   1-2-3-4-5-6-7'
}

const numEmojis = ['one', 'two', 'three', 'four', 'five', 'six', 'seven']

const checkRows = board => {
  for (const row of board) {
    const match = row.join('').match(/(XXXX)|(OOOO)/)
    if (match) {
      return match[0][0]
    }
  }
  return null
}

const checkColumns = board => {
  const colToText = i =>
    board[0][i] +
      board[1][i] +
      board[2][i] +
      board[3][i] +
      board[4][i] +
      board[5][i]

  for (let i = 0; i < 6; i++) {
    const match = colToText(i).match(/(XXXX)|(OOOO)/)
    if (match) {
      return match[0][0]
    }
  }
  return null
}

const checkDiagonals = board => {
  for (let row = 0; row < 3; row++) {
    // Starting top-left
    for (let col = 0; col < 4; col++) {
      if (board[row][col] !== ' ' &&
          board[row][col] === board[row + 1][col + 1] &&
          board[row][col] === board[row + 2][col + 2] &&
          board[row][col] === board[row + 3][col + 3]
      ) {
        return board[row][col]
      }
    }

    // Starting top-right
    for (let col = 3; col < 7; col++) {
      if (board[row][col] !== ' ' &&
          board[row][col] === board[row + 1][col - 1] &&
          board[row][col] === board[row + 2][col - 2] &&
          board[row][col] === board[row + 3][col - 3]
      ) {
        return board[row][col]
      }
    }
  }
  return null
}

const checkFull = board => {
  for (const row of board) {
    for (const col of row) {
      if (col === ' ') {
        return null
      }
    }
  }
  return routine.tie
}

const getTurn = board => {
  let x = 0
  let o = 0
  for (const row of board) {
    for (const col of row) {
      if (col === 'X') {
        x += 1
      } else if (col === 'O') {
        o += 1
      }
    }
  }
  return x > o ? 'O' : 'X'
}

const placeAt = (i, board, char) => {
  for (let y = 5; y >= 0; y--) {
    if (board[y][i] === ' ') {
      board[y][i] = char
      return true
    }
  }
  return false
}

const makeMove = (emoji, board) =>
  placeAt(numEmojis.indexOf(emoji), board, getTurn(board))

routine.build({
  startTriggers: ['connect 4', 'c4'],
  initialBoard: () => emptyBoard,
  turnChoiceEmojis: numEmojis,
  gameName: 'Connect 4',
  textFromBoard,
  checkWinner: board => checkRows(board) || checkColumns(board) || checkDiagonals(board) || checkFull(board),
  makeMove
})
