import re

_UNIT_SECONDS = {'h': 3600, 'm': 60, 's': 1}
_ORDER = ['h', 'm', 's']


def parse_duration(text):
    if not isinstance(text, str):
        raise ValueError('duration must be a string')
    tokens = text.split()
    if not tokens:
        raise ValueError('empty duration')
    total = 0
    last_index = -1
    for token in tokens:
        match = re.fullmatch(r'(\d+)([a-zA-Z])', token)
        if not match:
            raise ValueError('invalid component: %r' % token)
        value, unit = int(match.group(1)), match.group(2).lower()
        if unit not in _UNIT_SECONDS:
            raise ValueError('unknown unit: %r' % unit)
        index = _ORDER.index(unit)
        if index <= last_index:
            raise ValueError('out of order or repeated unit: %r' % unit)
        last_index = index
        total += value * _UNIT_SECONDS[unit]
    return total
