package com.mingzuozhibi.modules.disc;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.Instant;
import java.time.LocalDate;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.function.Predicate;

import static java.util.Comparator.*;
import static java.util.stream.Collectors.toCollection;

@Service
public class GroupService {

    @Autowired
    private GroupRepository groupRepository;

    @Transactional
    public long getFetchCount() {
        return groupRepository.findActiveDiscs().stream()
            .map(Disc::getAsin)
            .distinct().count();
    }

    @Transactional
    public Set<Disc> findNeedUpdateDiscs() {
        Set<Disc> result = new LinkedHashSet<>();

        List<Disc> discs = groupRepository.findActiveDiscs();

        Instant h6ago = Instant.now().minus(6, ChronoUnit.HOURS);
        Predicate<Disc> isNeedQuickFetch = disc ->
            disc.getUpdateTime() == null || disc.getUpdateTime().isBefore(h6ago);
        discs.stream().filter(isNeedQuickFetch)
            .sorted(comparing(Disc::getUpdateTime, nullsLast(naturalOrder())))
            .forEach(result::add);

        Instant h2ago = Instant.now().minus(2, ChronoUnit.HOURS);
        Predicate<Disc> isNeedAfterFetch = disc ->
            disc.getUpdateTime() != null && disc.getUpdateTime().isBefore(h2ago);
        discs.stream().filter(isNeedAfterFetch)
            .forEach(result::add);

        return result;
    }

    @Transactional
    public Set<Disc> findNeedRecordDiscs() {
        LocalDate target = LocalDate.now().minusDays(7);
        return groupRepository.findActiveDiscs().stream()
            .filter(disc -> disc.getReleaseDate().isAfter(target))
            .collect(toCollection(LinkedHashSet::new));
    }

    @Transactional
    public void updateGroupModifyTime() {
        groupRepository.findByEnabled(true).forEach(group -> {
            findLastUpdate(group).ifPresent(disc -> {
                group.setModifyTime(disc.getUpdateTime());
            });
        });
    }

    private Optional<Disc> findLastUpdate(Group group) {
        return group.getDiscs().stream()
            .max(comparing(Disc::getUpdateTime, nullsFirst(naturalOrder())));
    }

}

@@ -804,59 +804,8 @@
 ) %7B%0A
-        Set%3CDisc%3E result = new LinkedHashSet%3C%3E();%0A%0A
     
@@ -875,24 +875,120 @@
     
-Instant h6ago = 
+Predicate%3CDisc%3E isNeedQuick = disc -%3E disc.getUpdateTime() == null %7C%7C%0A            disc.getUpdateTime().isBefore(
 Inst
@@ -1003,17 +1003,17 @@
 ).minus(
-6
+5
 , Chrono
@@ -1015,32 +1015,33 @@
 hronoUnit.HOURS)
+)
 ;%0A        Predic
@@ -1052,29 +1052,24 @@
 Disc%3E isNeed
-Quick
 Fetch = disc
@@ -1067,36 +1067,24 @@
 ch = disc -%3E
-%0A           
  disc.getUpd
@@ -1093,26 +1093,38 @@
 eTime() 
-=
+!
 = null 
-%7C%7C
+&&%0A           
  disc.ge
@@ -1150,13 +1150,99 @@
 ore(
-h6ago
+Instant.now().minus(1, ChronoUnit.HOURS));%0A%0A        Set%3CDisc%3E result = new LinkedHashSet%3C%3E(
 );%0A 
@@ -1254,32 +1254,45 @@
   discs.stream()
+%0A            
 .filter(isNeedQu
@@ -1294,21 +1294,16 @@
 eedQuick
-Fetch
 )%0A      
@@ -1410,25 +1410,24 @@
 ::add);%0A
-%0A
         
 Instant 
@@ -1422,207 +1422,8 @@
     
-Instant h2ago = Instant.now().minus(2, ChronoUnit.HOURS);%0A        Predicate%3CDisc%3E isNeedAfterFetch = disc -%3E%0A            disc.getUpdateTime() != null && disc.getUpdateTime().isBefore(h2ago);%0A        
 disc
@@ -1432,16 +1432,29 @@
 stream()
+%0A            
 .filter(
@@ -1459,21 +1459,16 @@
 r(isNeed
-After
 Fetch)%0A 
@@ -1501,17 +1501,16 @@
 ::add);%0A
-%0A
         

Change fetch conditions