from typing import List
from typing import Tuple
from typing import Dict


def group_ext_by_type(data: List[Tuple[str, int]],
                      ext_and_group: Dict[str, str]) -> Dict[str, List[Tuple[str, int]]]:
    """Group file extensions by type.

    Default ext_and_group:
    archives, audio, audio/video, data, documents, executables, fonts, images,
    Python related extensions, videos, and other files.
    User-defined ext_and_group:
    may be created from configuration file.
    Initial storage: dict with items like {'documents': [], 'images': [], ...}
    key - group name, value - empty list.
    'other': reserved key.
    :param data: list with items like [('png', 8), ('txt', 25), ...]
    :param ext_and_group: dict with items like {'png': 'image', 'txt': documents, ...}
    :return: sorted dict with items like {'documents': [('txt', 25), ...], 'images': [('png', 8), ...], ...}
    """
    # storage: Dict[str, list]
    # local scope important
    storage = dict.fromkeys(sorted(set(ext_and_group.values())), [])
    other = []
    for (ext, freq) in data:
        item_type = ext_and_group.get(ext.lower(), 'other')
        if item_type == 'other':
            other.append((ext, freq))
        else:
            if storage.get(item_type):
                storage[item_type].append((ext, freq))
            else:
                storage[item_type] = [(ext, freq)]
    if other:
        storage.update({'other': other})
    return storage