from src.Board.board import Board
import random

class AI:
    def __init__(self) -> None:
        """
        :params:
            None
        :returns:
            None
        
        This is the constructor for the AI class. It is called when the game class is initialized. It does not take any parameters.
        """

    def get_move(self, board_state: Board) -> int:
        """
        :params:
            board_state: Board
        :returns:
            int
        
        This function is called by the game class to get the AI's move. It should return an integer between 0 and 6. This integer represents the column the AI wants to play in.
        """
        move=self.__check_imeadiate_win_or_loss(board_state,2)
        if move is not None:
            return move
        move=self.__check_imeadiate_win_or_loss(board_state,1)
        if move is not None:
            return move
        moves=self.__get_all_possible_moves(board_state)
        return random.choice(moves)

    def __get_all_possible_moves(self, board_state: Board) -> list[int]:
        """
        :params:
            board_state: Board
        :returns:
            list[int]

        This function returns a list of all possible moves the AI can make. This is used to randomly select a move if the AI can't win or lose in the next move.    
        """
        moves=[]
        for i in range(7):
            if board_state.check_cell(5,i)==None:
                moves.append(i)
        return moves

    def __check_imeadiate_win_or_loss(self, board_state: Board,player: int) -> int:
        """
        :params:
            board_state: Board
            player: int
        :returns:
            int

        This function checks if the AI can win or lose in the next move. If it can, it returns the column it should play in. If it can't, it returns None.
        """
        for column in range(7):
            for row in range(6):
                if column + 3 < 7:
                    to_check = [board_state.get_board()[column+i][row] for i in range(4)]
                    if to_check.count(player) == 3 and to_check.count(None) == 1 and (row==0 or board_state.check_cell(row-1,column+to_check.index(None)) is not None):
                            return column + to_check.index(None)
                if row + 3 < 6:
                    to_check = [board_state.get_board()[column][row+i] for i in range(4)]
                    if to_check.count(player) == 3 and to_check.count(None) == 1:
                        return column
                if column + 3 < 7 and row + 3 < 6:
                    to_check = [board_state.get_board()[column+i][row+i] for i in range(4)]
                    if to_check.count(player) == 3 and to_check.count(None) == 1 and (row-to_check.index(None) == 0 or board_state.check_cell(row+to_check.index(None)-1,column+to_check.index(None)) is not None):
                        return column + to_check.index(None)
                if column + 3 < 7 and row - 3 >= 0:
                    to_check = [board_state.get_board()[column+i][row-i] for i in range(4)]
                    if to_check.count(player) == 3 and to_check.count(None) == 1 and (row-to_check.index(None) == 0 or board_state.check_cell(row-to_check.index(None)-1,column+to_check.index(None)) is not None):
                        return column + to_check.index(None)
        return None



