import java.sql.*;
import java.util.*;

public class TimeRangeSelector {

    public List<YourEntity> selectNonOverlappingRecords() {
        List<YourEntity> selectedRecords = new ArrayList<>();
        Set<String> timeRanges = new HashSet<>();

        // 查询所有记录
        List<YourEntity> allRecords = this.list();

        for (YourEntity record : allRecords) {
            Timestamp startTime = record.getStartTime();
            Timestamp endTime = record.getEndTime();
            String parentId = record.getParentId();
            String satelliteId = record.getSatelliteId();

            String rangeKey = startTime + "-" + endTime;

            // 检查时间段是否重合
            boolean overlaps = timeRanges.stream().anyMatch(existingRange ->
                    isOverlapping(existingRange, startTime, endTime));

            if (!overlaps) {
                selectedRecords.add(record);
                timeRanges.add(rangeKey);

                if (selectedRecords.size() >= 200) {
                    break;
                }
            }
        }
        return selectedRecords;
    }

    private boolean isOverlapping(String existingRange, Timestamp startTime, Timestamp endTime) {
        String[] parts = existingRange.split("-");
        Timestamp existingStart = Timestamp.valueOf(parts[0]);
        Timestamp existingEnd = Timestamp.valueOf(parts[1]);

        return !(endTime.before(existingStart) || startTime.after(existingEnd));
    }

    // 你的实体类
    public static class YourEntity {
        private Timestamp startTime;
        private Timestamp endTime;
        private String parentId;
        private String satelliteId;

        // Getters and Setters
        public Timestamp getStartTime() {
            return startTime;
        }

        public void setStartTime(Timestamp startTime) {
            this.startTime = startTime;
        }

        public Timestamp getEndTime() {
            return endTime;
        }

        public void setEndTime(Timestamp endTime) {
            this.endTime = endTime;
        }

        public String getParentId() {
            return parentId;
        }

        public void setParentId(String parentId) {
            this.parentId = parentId;
        }

        public String getSatelliteId() {
            return satelliteId;
        }

        public void setSatelliteId(String satelliteId) {
            this.satelliteId = satelliteId;
        }
    }

    public static List<DataRecord> findFilteredData(List<DataRecord> dataList, int limit) {
        Map<String, List<DataRecord>> groupedBySatelliteId = dataList.stream()
                .collect(Collectors.groupingBy(DataRecord::getSatelliteId));

        Set<String> usedParentIds = new HashSet<>();
        List<DataRecord> finalResult = new ArrayList<>();

        for (Map.Entry<String, List<DataRecord>> entry : groupedBySatelliteId.entrySet()) {
            String satelliteId = entry.getKey();
            List<DataRecord> satelliteData = entry.getValue();

            // Sort by start_time to help with non-overlapping check
            satelliteData.sort(Comparator.comparing(DataRecord::getStartTime));

            List<DataRecord> nonOverlappingRecords = new ArrayList<>();

            for (DataRecord record : satelliteData) {
                // Skip if the parentId is already used
                if (usedParentIds.contains(record.getParentId())) {
                    continue;
                }

                // Check if start_time and end_time overlap for same satellite_id
                boolean isOverlapping = nonOverlappingRecords.stream().anyMatch(r ->
                        r.getEndTime().isAfter(record.getStartTime()) || r.getStartTime().isBefore(record.getEndTime()));

                if (!isOverlapping) {
                    nonOverlappingRecords.add(record);
                    usedParentIds.add(record.getParentId());
                    finalResult.add(record);

                    // Stop if we have enough results
                    if (finalResult.size() >= limit) {
                        return finalResult;
                    }
                }
            }
        }

        return finalResult;
    }
}
