package io.wealthwizards.appsynctesting.utils;

import java.util.Collections;
import java.util.Comparator;
import java.util.Map;
import java.util.stream.Collectors;

public final class List {
    public <T> java.util.List<T> copyAndRetainAll(java.util.List<T> toCopy, java.util.List<T> toRetain) {
        return toCopy.stream()
                .filter(toRetain::contains)
                .collect(Collectors.toList());
    }

    public <T> java.util.List<T> copyAndRemoveAll(java.util.List<T> toCopy, java.util.List<T> toRemove) {
        return toCopy.stream()
                .filter(item -> !toRemove.contains(item))
                .collect(Collectors.toList());
    }

    public java.util.List<?> sortList(java.util.List<?> toSort, boolean descending, String property) {
        try {
            var types = toSort.stream()
                    .map(Object::getClass)
                    .distinct()
                    .collect(Collectors.toList());

            if (types.size() != 1) {
                return toSort;
            }

            var example = toSort.get(0);

            if (example instanceof Map) {
                Comparator<Map<String, ? extends Comparable>> comparator = (Map<String, ? extends Comparable> a, Map<String, ? extends Comparable> b) -> {
                    var valueA = a.get(property);
                    var valueB = b.get(property);

                    var direction = valueA.compareTo(valueB);

                    return descending ? -direction : direction;
                };

                var mapList = (java.util.List<Map<String, ? extends Comparable>>) toSort;

                return mapList.stream()
                        .sorted(comparator)
                        .collect(Collectors.toList());
            }

            var sorted = toSort.stream()
                    .sorted()
                    .collect(Collectors.toList());

            if (descending) {
                Collections.reverse(sorted);
            }

            return sorted;
        } catch (Exception e) {
            return toSort;
        }
    }
}
