from typing import Optional
import re
import string


def get_dart_well_index(coordinate: Optional[str]) -> Optional[int]:
    """Determines a well index from a coordinate; otherwise returns None. Well indices are determined by evaluating the
    row position, then column position. E.g. A04 -> 4, B04 -> 16.

    Arguments:
        coordinate {Optional[str]} -- The coordinate for which to determine the well index

    Returns:
        int -- the well index
    """
    if not coordinate:
        return None

    regex = r"^([A-Z])(\d{1,2})$"
    m = re.match(regex, coordinate)

    # assumes a 96-well plate with A1 - H12 wells
    if m is not None:
        col_idx = int(m.group(2))
        if 1 <= col_idx <= 12:
            multiplier = string.ascii_lowercase.index(m.group(1).lower())
            well_index = (multiplier * 12) + col_idx
            if 1 <= well_index <= 96:
                return well_index

    return None