from typing import List
from typing import Optional
from typing import Any


def navigation(options: List, **kwargs) -> Optional[Any]:
    """
    Displays A List of Options and Handles User Input in Selecting One of the Provided Options
    :param options: List of Options to get a User to Choose From
    :param kwargs: Additional Arguments to Modify how the Options are Displayed

    :keyword attribute: The Object Attribute Name for Each Option to Be Displayed and Sorted by (If Sorted is True)
    :keyword title: A title to Describe the Individual Options Provided
    :keyword input_text: Modify the Selection Text for the Options
    :keyword sort: Sort the Options by their Attribute Name (If attribute is also Provided)

    :return: The Selected Option from the Options or None
    """
    # Handle kwargs
    attribute = kwargs.get('attribute', None)
    title = kwargs.get('title', '')
    input_text = kwargs.get('input', "Enter {} Number to Select ['c' to Exit]: ".format(title))
    sort = kwargs.get('sort', False)

    if sort and attribute is not None:
        options = sorted(options, key=lambda element: getattr(element, attribute))
    if not options:
        return None  # No Options to Chose From
    while True:
        for i in range(len(options)):
            print("[{}] {}".format(i + 1, getattr(options[i], attribute) if attribute is not None else str(options[i])))
        choice = input(input_text + "\n")
        if choice.isalpha():
            return None  # No Choice Made
        try:
            choice = int(choice)
            if choice > len(options) or choice <= 0:
                raise ValueError
            return options[choice - 1]  # maybe just return the index
        except (TypeError, ValueError):
            print("Invalid Selection")