package com.nilhcem.droidcontn.data.app;

import com.nilhcem.droidcontn.data.app.model.Schedule;
import com.nilhcem.droidcontn.data.app.model.Speaker;
import com.nilhcem.droidcontn.data.database.DbMapper;
import com.nilhcem.droidcontn.data.database.dao.SelectedSessionsDao;
import com.nilhcem.droidcontn.data.database.dao.SessionsDao;
import com.nilhcem.droidcontn.data.database.dao.SpeakersDao;
import com.nilhcem.droidcontn.data.network.DroidconService;

import java.util.List;

import javax.inject.Inject;
import javax.inject.Singleton;

import rx.Observable;
import rx.Subscriber;

@Singleton
public class DataProvider {

    private final DbMapper dbMapper;
    private final DroidconService service;
    private final SpeakersDao speakersDao;
    private final SessionsDao sessionsDao;
    private final SelectedSessionsDao selectedSessionsDao;

    @Inject
    public DataProvider(DbMapper dbMapper, DroidconService service, SpeakersDao speakersDao, SessionsDao sessionsDao, SelectedSessionsDao selectedSessionsDao) {
        this.dbMapper = dbMapper;
        this.service = service;
        this.speakersDao = speakersDao;
        this.sessionsDao = sessionsDao;
        this.selectedSessionsDao = selectedSessionsDao;
    }

    public Observable<Schedule> getSchedule() {
        selectedSessionsDao.init();
        return Observable.combineLatest(getSpeakers(), getSessions(), (speakers, sessions) ->
                AppMapper.toSchedule(sessions, AppMapper.speakersToMap(speakers)));
    }

    public Observable<List<Speaker>> getSpeakerList() {
        return getSpeakers()
                .map(AppMapper::mapSpeakers);
    }

    private Observable<List<com.nilhcem.droidcontn.data.network.model.Speaker>> getSpeakers() {
        return Observable.create(subscriber -> {
            speakersDao.getSpeakers()
                    .map(dbMapper::toNetworkSpeaker)
                    .subscribe(dbSpeakers -> {
                        if (dbSpeakers.isEmpty()) {
                            // TODO: get from embedded json
                        } else {
                            subscriber.onNext(dbSpeakers);
                        }

                        if (!subscriber.isUnsubscribed()) {
                            getSpeakersFromNetwork(subscriber);
                        }
                    }, subscriber::onError);
        });
    }

    private void getSpeakersFromNetwork(Subscriber<? super List<com.nilhcem.droidcontn.data.network.model.Speaker>> subscriber) {
        service.loadSpeakers()
                .subscribe(networkSpeakers -> {
                    subscriber.onNext(networkSpeakers);
                    speakersDao.saveSpeakers(dbMapper.fromNetworkSpeakers(networkSpeakers));
                }, throwable -> subscriber.onCompleted(), subscriber::onCompleted);
    }

    private Observable<List<com.nilhcem.droidcontn.data.network.model.Session>> getSessions() {
        return Observable.create(subscriber -> {
            sessionsDao.getSessions()
                    .map(dbMapper::toNetworkSession)
                    .subscribe(dbSessions -> {
                        if (dbSessions.isEmpty()) {
                            // TODO: get from embedded json
                        } else {
                            subscriber.onNext(dbSessions);
                        }

                        if (!subscriber.isUnsubscribed()) {
                            getSessionsFromNetwork(subscriber);
                        }
                    }, subscriber::onError);
        });
    }

    private void getSessionsFromNetwork(Subscriber<? super List<com.nilhcem.droidcontn.data.network.model.Session>> subscriber) {
        service.loadSessions()
                .subscribe(networkSessions -> {
                    subscriber.onNext(networkSessions);
                    sessionsDao.saveSessions(dbMapper.fromNetworkSessions(networkSessions));
                }, throwable -> subscriber.onCompleted(), subscriber::onCompleted);
    }
}

@@ -1776,30 +1776,16 @@
 riber -%3E
- %7B%0A           
  speaker
@@ -1795,36 +1795,32 @@
 o.getSpeakers()%0A
-    
                 
@@ -1860,36 +1860,32 @@
                 
-    
 .subscribe(dbSpe
@@ -1887,36 +1887,32 @@
 dbSpeakers -%3E %7B%0A
-    
                 
@@ -1959,36 +1959,32 @@
                 
- 
-   
 // TODO: get fro
@@ -2011,36 +2011,32 @@
                 
-    
 %7D else %7B%0A       
@@ -2044,36 +2044,32 @@
                 
- 
-   
 subscriber.onNex
@@ -2095,36 +2095,32 @@
                 
-    
 %7D%0A%0A             
@@ -2118,36 +2118,32 @@
                 
-  
-  
 if (!subscriber.
@@ -2154,36 +2154,32 @@
 subscribed()) %7B%0A
-    
                 
@@ -2238,34 +2238,26 @@
             
-  
-  %7D%0A    
+%7D%0A
             
@@ -2279,35 +2279,24 @@
 er::onError)
-;%0A        %7D
 );%0A    %7D%0A%0A  

Remove useless curly braces