import re


def get_decimal_degrees_from_dms_string(dms_string):
    """
    Convert set data representing lat lon as a Degree Minute Second (DMS) value to Decimal Degrees
    using formula: Decimal Degrees = degrees + (minutes/60) + (seconds/3600)

    ACO coordinate set data comes in 2 varieties:
    LATS (e.g. LATS:431026N1165028W) and LATM (e.g. LATM:4302N11553W)
    Assumptions:
        LATS format is Degrees Minutes Seconds and broken down as follows:
        Index: 0  1  2  3  4  5  6  7
        LATS:  43 10 26 N 116 50 28 W

    """
    index_dict = {
        "lat_degree_index": 0,
        "lat_minute_index": 1,
        "lat_second_index": 2,
        "lat_millisecond_index": 3,
        "lat_direction_index": 4,
        "lon_degree_index": 5,
        "lon_minute_index": 6,
        "lon_second_index": 7,
        "lon_millisecond_index": 8,
        "lon_direction_index": 9,
    }

    pattern = r"\s*(\d{2})+(\d{2})+(\d{2})+(\.\d{2})+([N|S])*(\d{3})+(\d{2})+(\d{2})+(\.\d{2})+([E|W])"

    try:
        lat_lon_set = re.findall(pattern, dms_string)[0]
    except IndexError as exc:
        raise ValueError(
            f"There was an error parsing coordinate: {dms_string}."
        ) from exc

    lat_decimal = (
        int(lat_lon_set[index_dict["lat_degree_index"]])
        + int(lat_lon_set[index_dict["lat_minute_index"]]) / 60
    )
    lon_decimal = (
        int(lat_lon_set[index_dict["lon_degree_index"]])
        + int(lat_lon_set[index_dict["lon_minute_index"]]) / 60
    )

    lat_decimal += (
        float(
            lat_lon_set[index_dict["lat_second_index"]]
            + lat_lon_set[index_dict["lat_millisecond_index"]]
        )
        / 3600
    )
    lon_decimal += (
        float(
            lat_lon_set[index_dict["lon_second_index"]]
            + lat_lon_set[index_dict["lon_millisecond_index"]]
        )
        / 3600
    )

    if (
        lat_lon_set[index_dict["lon_direction_index"]] == "S"
        or lat_lon_set[index_dict["lon_direction_index"]] == "W"
    ):
        lon_decimal *= -1

    # GeoJSON coordinates are in (lon, lat) format
    return [lon_decimal, lat_decimal]
