package com.robotzero.counter.service;

import com.robotzero.counter.domain.ColumnType;
import com.robotzero.counter.domain.TimerType;
import com.robotzero.counter.domain.clock.CurrentClockState;
import com.robotzero.counter.event.ButtonState;
import com.robotzero.counter.event.ButtonType;
import com.robotzero.counter.event.action.Action;
import com.robotzero.counter.event.action.ActionType;
import com.robotzero.counter.event.action.ClickAction;
import com.robotzero.counter.event.action.TickAction;
import io.reactivex.Observable;
import io.reactivex.subjects.PublishSubject;

import java.time.Duration;
import java.time.LocalTime;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.stream.IntStream;

import static java.lang.Math.toIntExact;

public class ResetService {

    private CurrentClockState currentClockState;

    public ResetService(PublishSubject<CurrentClockState> currentClockStateObservable) {
        currentClockStateObservable.subscribe(currentClockState -> {
            this.currentClockState = currentClockState;
        });
    }

    public Observable<? extends Action> getActions(ButtonType buttonType, ButtonState buttonState) {
        howManyTicks();
        if (buttonType.equals(ButtonType.RIGHT)) {
            return Observable.create(emitter -> {
                emitter.onNext(new ClickAction(ActionType.valueOf(buttonType.name()), buttonState));
                IntStream.range(0, howManyTicks().get(0)).forEach(index -> {
                   emitter.onNext(new TickAction(-40, ColumnType.SECONDS, TimerType.SCROLL));
                });
                IntStream.range(0, howManyTicks().get(1)).forEach(index -> {
                    emitter.onNext(new TickAction(-40, ColumnType.MINUTES, TimerType.SCROLL));
                });
                IntStream.range(0, howManyTicks().get(2)).forEach(index -> {
                    emitter.onNext(new TickAction(-40, ColumnType.HOURS, TimerType.SCROLL));
                });
                emitter.onComplete();
            });
//            return Observable.just(new ClickAction(
//                    ActionType.valueOf(buttonType.name()),
//                    buttonState
//            ), new TickAction(-40, ColumnType.SECONDS, TimerType.SCROLL));
        }
        return Observable.just(new ClickAction(
                        ActionType.valueOf(buttonType.name()),
                        buttonState
                )
        );
    }

    private List<Integer> howManyTicks() {
        CurrentClockState currentClockState1 = Optional.ofNullable(this.currentClockState).orElseGet(() -> new CurrentClockState(timeToReset().getSecond(), timeToReset().getMinute(), timeToReset().getHour(), null, false, false, false));
        LocalTime toReset = timeToReset();
        int elapsedSeconds = toIntExact(Duration.between(timeToReset(), LocalTime.of(toReset.getHour(), toReset.getMinute(), currentClockState1.getSecond())).toSeconds());
        int elapsedMinutes = toIntExact(Duration.between(timeToReset(), LocalTime.of(toReset.getHour(), currentClockState1.getMinute(), toReset.getSecond())).toMinutes());
        int elapsedHours = toIntExact(Duration.between(timeToReset(), LocalTime.of(currentClockState1.getHour(), toReset.getMinute(), toReset.getSecond())).toHours());
        return Arrays.asList(elapsedSeconds, elapsedMinutes, elapsedHours);
    }

    private LocalTime timeToReset() {
        return LocalTime.of(22, 01, 10);
    }
}

@@ -630,16 +630,44 @@
 alTime;%0A
+import java.util.ArrayList;%0A
 import j
@@ -683,16 +683,16 @@
 Arrays;%0A
-
 import j
@@ -733,16 +733,90 @@
 tional;%0A
+import java.util.concurrent.TimeUnit;%0Aimport java.util.stream.Collectors;%0A
 import j
@@ -1389,76 +1389,73 @@
     
-return Observable.create(emitter -%3E %7B%0A                emitter.onNext
+List%3CAction%3E actions = new ArrayList%3C%3E();%0A            actions.add
 (new
@@ -1537,61 +1537,257 @@
     
-    IntStream.range(0, howManyTicks().get(0)).forEach
+List%3CInteger%3E tickNumber = howManyTicks();%0A            int seconds = tickNumber.get(0);%0A            int minutes = tickNumber.get(1);%0A            int hours = tickNumber.get(2);%0A            actions.addAll(IntStream.range(0, Math.abs(seconds)).mapToObj
 (ind
@@ -1810,34 +1810,23 @@
         
-   emitter.onNext(
+return 
 new Tick
@@ -1824,35 +1824,39 @@
  new TickAction(
--40
+seconds
 , ColumnType.SEC
@@ -1870,33 +1870,32 @@
 imerType.SCROLL)
-)
 ;%0A              
@@ -1896,81 +1896,115 @@
     
-    %7D);%0A                IntStream.range(0, howManyTicks().get(1)).forEach
+%7D).collect(Collectors.toList()));%0A            actions.addAll(IntStream.range(0, Math.abs(minutes)).mapToObj
 (ind
@@ -2027,35 +2027,23 @@
         
-    emitter.onNext(
+return 
 new Tick
@@ -2041,35 +2041,39 @@
  new TickAction(
--40
+minutes
 , ColumnType.MIN
@@ -2087,33 +2087,32 @@
 imerType.SCROLL)
-)
 ;%0A              
@@ -2113,81 +2113,113 @@
     
- 
-   %7D);%0A                IntStream.range(0, howManyTicks().get(2)).forEach
+%7D).collect(Collectors.toList()));%0A            actions.addAll(IntStream.range(0, Math.abs(hours)).mapToObj
 (ind
@@ -2246,27 +2246,15 @@
     
-    emitter.onNext(
+return 
 new 
@@ -2256,35 +2256,37 @@
  new TickAction(
--40
+hours
 , ColumnType.HOU
@@ -2302,31 +2302,26 @@
 Type.SCROLL)
-)
 ;%0A
-    
             
@@ -2326,287 +2326,179 @@
   %7D)
-;%0A                emitter.onComplete();%0A            %7D);%0A//            return Observable.just(new ClickAction(%0A//                    ActionType.valueOf(buttonType.name()),%0A//                    buttonState%0A//            ), new TickAction(-40, ColumnType.
+.collect(Collectors.toList()));%0A%0A            return Observable.zip(Observable.fromIterable(actions), Observable.interval(300, TimeUnit.MILLI
 SECONDS
+)
 , 
-TimerType.SCROLL)
+(left, right) -%3E left
 );%0A 

reset pt 2