"""BTVN, Python3: duyệt danh sách chung; toàn bộ dữ liệu là giả định.

python3 g11-cs-danh-sach-chung.py chung g11-cs-lien-he.inp "Mẫu A" "Mẫu B"
python3 g11-cs-danh-sach-chung.py de-xuat g11-cs-nhom.inp
python3 g11-cs-danh-sach-chung.py nhom g11-cs-nhom.inp "Mẫu A"
python3 g11-cs-danh-sach-chung.py cap g11-cs-lien-he.inp
python3 g11-cs-danh-sach-chung.py cap g11-cs-nhom.inp
Mỗi tài khoản là một nhãn duy nhất; từng danh sách không lặp phần tử.
"""
import argparse


def read_lists(filename):
    names, lists = [], []
    with open(filename, encoding='utf-8') as source:
        for number, line in enumerate(source, 1):
            if not line.strip():
                continue
            if line.count(':') != 1:
                raise ValueError(f'Dòng {number}: cần một dấu hai chấm.')
            name, raw = line.split(':', 1)
            name = name.strip()
            if not name or name in names:
                raise ValueError(f'Dòng {number}: tên trống hoặc trùng.')
            values = [x.strip() for x in raw.split(',')] if raw.strip() else []
            if any(not x for x in values) or len(values) != len(set(values)):
                raise ValueError(f'Dòng {number}: phần tử trống hoặc trùng.')
            names.append(name)
            lists.append(values)
    return names, lists


def find_name(names, target):
    for i in range(len(names)):
        if names[i] == target:
            return i
    return -1


def common_values(A, B):
    result = []
    for value in A:
        if value in B:
            result.append(value)
    return result


def recommendations(names, groups):
    result = []
    for i in range(len(names)):
        suggested = []
        for j in range(len(names)):
            if i != j and len(common_values(groups[i], groups[j])) >= 3:
                suggested.append(names[j])
        result.append((names[i], suggested))
    return result


def all_groups(groups):
    result = []
    for row in groups:
        for group in row:
            if group not in result:
                result.append(group)
    return result


def member_count(groups, group):
    count = 0
    for row in groups:
        if group in row:
            count += 1
    return count


def suggested_group(groups, index):
    best, best_count = None, 0
    for group in all_groups(groups):
        if group not in groups[index]:
            count = member_count(groups, group)
            if best is None or count > best_count:
                best, best_count = group, count
    return best, best_count


def best_pair(names, lists):
    best_names = None, None
    best_count = -1
    for i in range(len(names) - 1):
        for j in range(i + 1, len(names)):
            count = len(common_values(lists[i], lists[j]))
            if count > best_count:
                best_names = names[i], names[j]
                best_count = count
    if best_count < 0:
        return None, None, 0
    return best_names[0], best_names[1], best_count


def main():
    parser = argparse.ArgumentParser(description=__doc__)
    modes = parser.add_subparsers(dest='mode', required=True)
    for mode in ['chung', 'de-xuat', 'nhom', 'cap']:
        sub = modes.add_parser(mode)
        sub.add_argument('input')
        if mode == 'chung':
            sub.add_argument('first')
            sub.add_argument('second')
        elif mode == 'nhom':
            sub.add_argument('name')
    args = parser.parse_args()
    try:
        names, lists = read_lists(args.input)
        if args.mode == 'chung':
            first, second = find_name(names, args.first), find_name(names, args.second)
            if first < 0 or second < 0:
                raise ValueError('Không có tên cần tìm trong tệp.')
            values = common_values(lists[first], lists[second])
            print('Số phần tử chung:', len(values))
            print('Danh sách chung:', values)
        elif args.mode == 'de-xuat':
            for name, suggested in recommendations(names, lists):
                print(name + ':', suggested)
        elif args.mode == 'nhom':
            index = find_name(names, args.name)
            if index < 0:
                raise ValueError('Không có tên cần tìm trong tệp.')
            group, count = suggested_group(lists, index)
            if group is None:
                print('Không có nhóm chưa tham gia trong dữ liệu.')
            else:
                print('Nhóm gợi ý:', group)
                print('Số thành viên trong dữ liệu:', count)
        else:
            first, second, count = best_pair(names, lists)
            if first is None:
                print('Chưa có hai tài khoản để xét cặp.')
            else:
                print('Hai tài khoản:', (first, second))
                print('Số phần tử chung lớn nhất:', count)
    except (OSError, ValueError) as error:
        parser.exit(2, f'Dữ liệu không phù hợp: {error}\n')


if __name__ == '__main__':
    main()
