from typing import Dict
from typing import Any
from typing import List


def _create_group_codes_names(
    contact_models: Dict[str, Any], assort_bys: Dict[str, List[str]]
) -> Dict[str, str]:
    """Create a name for each contact models group codes.

    The group codes are either found in the initial states or are a factorization of one
    or multiple variables in the initial states.

    ``"is_factorized"`` can be set in contact models to indicate that the assortative
    variable is already factorized which saves memory.

    """
    group_codes_names = {}
    for name, model in contact_models.items():
        is_factorized = model.get("is_factorized", False)
        n_assort_bys = len(assort_bys[name])
        if is_factorized and n_assort_bys != 1:
            raise ValueError(
                f"'is_factorized' is 'True' for contact model {name}, but there is not "
                f"one assortative variable, but {n_assort_bys}."
            )
        elif is_factorized:
            group_codes_names[name] = assort_bys[name][0]
        else:
            group_codes_names[name] = f"group_codes_{name}"

    return group_codes_names