from typing import List
from typing import Callable
from typing import Tuple


def get_score_house(
    board: List[List[str]],
    func_get_header_col: Callable[[List[List[str]]], List[str]],
    func_get_header_row: Callable[[List[List[str]]], List[str]],
    func_get_building_around: Callable[[List[List[str]], str], Tuple[str]],
) -> Tuple[int]:
    """
        Calculate the score for the building - house (HSE).
        Score 1: If there are any factory around the house.
        Score x + 2y: 
            If there are not factory around the house, 
            where x = total count of house + shop
            where y = total count of beach

        Parameters
        ----------
        board: List[List[str]]
            2D array containing all the game detail, including column header, row header and placed buildings.

        func_get_header_col: Callable[[List[List[str]]], List[str]]
            A function that will accept board as parameter and return column header list as result.

            Parameters
            ----------
            board: List[List[str]]

            Returns
            -------
            column_header_list: List[str]
                A list containing all the column headers.

        fun_get_header_row: Callable[[List[List[str]]], List[str]]
            A function that will accept board as paraemter and return the row header list as result.

            Parameters
            ----------
            board: List[List[str]]

            Returns
            -------
            row_header_list: List[str]
                A list containing all the row headers.

        fun_get_building_around: Callable[[List[List[str]], str], Tuple[str]]
            A function that will accept board and location as parameter and return a tuple containing all the building around the location.

            Parameters
            ----------
            board: List[List[str]]

            location: str
                Use to locate the cell on the board.

            Returns
            -------
            building_tuple: tuple
                A tuple containing all the building around the given location.

        Returns
        -------
        score: Tuple[int]
            A list containing all the score for the specific building - house (HSE).
    """

    type = 'HSE'
    score_list = []

    col_header_list = func_get_header_col(board)
    row_header_list = func_get_header_row(board)

    for idx_row, row in enumerate(board):
        for idx_col, col in enumerate(row):
            if type != col:
                continue

            score = 0
            cell = col_header_list[idx_col] + row_header_list[idx_row]
            building_list = func_get_building_around(board, cell)

            if 'FAC' in building_list:
                score = 1
            else:
                count_beach = building_list.count('BCH')
                count_house = building_list.count('HSE')
                count_shop = building_list.count('SHP')

                score = count_beach * 2 + count_house + count_shop

            score_list.append(score)
    return *score_list,