package com.marverenic.music.data.store;

import android.content.Context;
import android.support.annotation.Nullable;

import com.marverenic.music.R;
import com.marverenic.music.instances.AutoPlaylist;
import com.marverenic.music.instances.Playlist;
import com.marverenic.music.instances.Song;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import rx.Observable;
import rx.subjects.BehaviorSubject;

public class LocalPlaylistStore implements PlaylistStore {

    private Context mContext;
    private BehaviorSubject<List<Playlist>> mPlaylists;

    public LocalPlaylistStore(Context context) {
        mContext = context;
    }

    @Override
    public Observable<Boolean> refresh() {
        return MediaStoreUtil.promptPermission(mContext).map(
                granted -> {
                    if (mPlaylists != null) {
                        mPlaylists.onNext(getAllPlaylists());
                    }
                    return granted;
                });
    }

    @Override
    public Observable<List<Playlist>> getPlaylists() {
        if (mPlaylists == null) {
            mPlaylists = BehaviorSubject.create();

            MediaStoreUtil.getPermission(mContext).subscribe(granted -> {
                if (granted) {
                    mPlaylists.onNext(getAllPlaylists());
                } else {
                    mPlaylists.onNext(Collections.emptyList());
                }
            });
        }
        return mPlaylists;
    }

    private List<Playlist> getAllPlaylists() {
        return MediaStoreUtil.getAllPlaylists(mContext);
    }

    @Override
    public Observable<List<Song>> getSongs(Playlist playlist) {
        return Observable.just(MediaStoreUtil.getPlaylistSongs(mContext, playlist));
    }

    @Override
    public Observable<List<Playlist>> searchForPlaylists(String query) {
        return Observable.just(MediaStoreUtil.searchForPlaylists(mContext, query));
    }

    @Override
    public String verifyPlaylistName(String playlistName) {
        if (playlistName == null || playlistName.trim().isEmpty()) {
            return mContext.getString(R.string.error_hint_empty_playlist);
        }

        if (MediaStoreUtil.findPlaylistByName(mContext, playlistName) != null) {
            return mContext.getString(R.string.error_hint_duplicate_playlist);
        }

        return null;
    }

    @Override
    public Playlist makePlaylist(String name) {
        return makePlaylist(name, null);
    }

    @Override
    public AutoPlaylist makePlaylist(AutoPlaylist model) {
        // TODO implement AutoPlaylists
        return null;
    }

    @Override
    public Playlist makePlaylist(String name, @Nullable List<Song> songs) {
        Playlist created = MediaStoreUtil.createPlaylist(mContext, name, songs);

        if (mPlaylists != null && mPlaylists.getValue() != null) {
            List<Playlist> updated = new ArrayList<>(mPlaylists.getValue());
            updated.add(created);
            Collections.sort(updated);

            mPlaylists.onNext(updated);
        }

        return created;
    }

    @Override
    public void removePlaylist(Playlist playlist) {
        MediaStoreUtil.deletePlaylist(mContext, playlist);

        if (mPlaylists != null && mPlaylists.getValue() != null) {
            List<Playlist> updated = new ArrayList<>(mPlaylists.getValue());
            updated.remove(playlist);

            mPlaylists.onNext(updated);
        }
    }

    @Override
    public void editPlaylist(Playlist playlist, List<Song> newSongs) {
        MediaStoreUtil.editPlaylist(mContext, playlist, newSongs);
    }

    @Override
    public void editPlaylist(AutoPlaylist replacementModel) {
        // TODO implement AutoPlaylists
    }

    @Override
    public void addToPlaylist(Playlist playlist, Song song) {
        MediaStoreUtil.appendToPlaylist(mContext, playlist, song);
    }

    @Override
    public void addToPlaylist(Playlist playlist, List<Song> songs) {
        MediaStoreUtil.appendToPlaylist(mContext, playlist, songs);
    }
}

@@ -392,16 +392,97 @@
 rvable;%0A
+import rx.android.schedulers.AndroidSchedulers;%0Aimport rx.schedulers.Schedulers;%0A
 import r
@@ -858,13 +858,8 @@
 ext)
-.map(
 %0A   
@@ -871,16 +871,67 @@
         
+.subscribeOn(Schedulers.io())%0A                .map(
 granted 
@@ -1333,16 +1333,85 @@
 Context)
+%0A                    .observeOn(Schedulers.io())%0A                    
 .subscri
@@ -1418,32 +1418,40 @@
 be(granted -%3E %7B%0A
+        
                 
@@ -1477,32 +1477,40 @@
                 
+        
 mPlaylists.onNex
@@ -1547,16 +1547,24 @@
         
+  
+      
 %7D else %7B
@@ -1564,16 +1564,24 @@
  else %7B%0A
+        
         
@@ -1632,24 +1632,32 @@
 ptyList());%0A
+        
             
@@ -1666,32 +1666,40 @@
   %7D%0A            
+        
 %7D);%0A        %7D%0A  
@@ -1721,16 +1721,73 @@
 laylists
+.asObservable().observeOn(AndroidSchedulers.mainThread())
 ;%0A    %7D%0A

Load playlists on background thread