package de.beyondsoft.ownchat.page.sharing;

import android.content.Context;
import android.net.Uri;
import android.support.annotation.NonNull;
import android.util.Log;

import org.greenrobot.eventbus.EventBus;

import java.io.File;
import java.util.ArrayList;

import javax.inject.Inject;
import javax.inject.Named;

import de.beyondsoft.ownchat.R;
import de.beyondsoft.ownchat.data.AppPrefsConstants;
import de.beyondsoft.ownchat.data.api.common.ErrorHandlingResponseConverter;
import de.beyondsoft.ownchat.data.api.responses.MessageResponse;
import de.beyondsoft.ownchat.data.api.services.ChatService;
import de.beyondsoft.ownchat.data.events.GroupUpdatedEvent;
import de.beyondsoft.ownchat.data.prefs.LongPreference;
import de.beyondsoft.ownchat.data.prefs.StringPreference;
import de.beyondsoft.ownchat.data.repository.GroupRealmRepository;
import de.beyondsoft.ownchat.data.repository.RealmProvider;
import de.beyondsoft.ownchat.data.repository.UserRealmRepository;
import de.beyondsoft.ownchat.data.repository.specifications.GroupByIdSpecification;
import de.beyondsoft.ownchat.data.repository.specifications.GroupSpecification;
import de.beyondsoft.ownchat.data.repository.specifications.MessageByIdSpecification;
import de.beyondsoft.ownchat.data.repository.specifications.UserByIdSpecification;
import de.beyondsoft.ownchat.model.Group;
import de.beyondsoft.ownchat.model.Message;
import de.beyondsoft.ownchat.page.mvp.MVPAbstractPresenter;
import de.beyondsoft.ownchat.utils.Constants;
import de.beyondsoft.ownchat.utils.FileUtils;
import de.beyondsoft.ownchat.utils.SystemUtils;
import de.beyondsoft.ownchat.utils.rx.RxUtils;
import okhttp3.MultipartBody;
import okhttp3.RequestBody;
import rx.Completable;
import rx.Observable;
import rx.Subscriber;
import rx.Subscription;
import rx.android.schedulers.AndroidSchedulers;
import rx.schedulers.Schedulers;


/**
 * Created by Lyndon on 03-Nov-2017.
 */

public class SharingPresenter extends MVPAbstractPresenter<SharingView> implements SharingView.Callback {
    @Inject
    Context mContext;

    @Inject
    ChatService mChatService;

    @Inject
    GroupRealmRepository mGroupRealmRepository;

    @Inject
    UserRealmRepository mUserRealmRepository;

    @Inject
    SystemUtils mSystemUtils;

    @Inject
    @Named(AppPrefsConstants.USER_ID)
    LongPreference mUserIdReference;

    @Inject
    SharingPresenter() {}

    @Override
    protected void afterAttachView(@NonNull SharingView view) {
        super.afterAttachView(view);
        view.setCallback(this);
        view.showProgress();
    }

    @Override
    protected void beforeDetachView(@NonNull SharingView view) {
        view.setCallback(null);
        super.beforeDetachView(view);
    }

    @Override
    public void loadGroups() {
        Subscription subscription = mChatService.getGroups()
                .flatMap(new ErrorHandlingResponseConverter<>())
                .flatMap(groupResponse -> {
                    if (groupResponse.response.groups != null) {
                        for (Group group : groupResponse.response.groups) {
                            group.userId = mUserIdReference.get();

                            if (group.lastMessage != null) {
                                group.lastMessage.status = Message.Status.DELIVERED;
                                group.lastMessage.userId = mUserIdReference.get();
                            }

                            mUserRealmRepository.update(group.users, new UserByIdSpecification()).subscribe();
                        }
                    }

                    return Observable.just(groupResponse.response.groups);
                })
                .compose(RxUtils.provideDefaultTransformer())
                .subscribe(this::groupsSuccess, this::groupsError);
        addSubscription(subscription);
    }

    private void groupsError(Throwable throwable) {
        if (mSystemUtils.isNetworkUnavailable()) {
            getView().showError(R.string.error_no_internet_connection);
            return;
        }

        getView().showError(R.string.error_something_went_wrong);
    }

    private void groupsSuccess(ArrayList<Group> groups) {
        mGroupRealmRepository.update(groups, new GroupByIdSpecification(mUserIdReference.get()))
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Subscriber<Object>() {
                    @Override
                    public void onCompleted() {
                        loadGroupsFromDB();
                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.e(SharingPresenter.class.getSimpleName(), e.getMessage(), e);
                    }

                    @Override
                    public void onNext(Object o) {
                        // nop here
                    }
                });
    }

    @Override
    public void loadGroupsFromDB() {
        GroupSpecification groupSpecification = new GroupSpecification(mUserIdReference.get());
        mGroupRealmRepository.queryForAll(groupSpecification)
                .map(ArrayList::new)
                .compose(RxUtils.provideDefaultTransformer())
                .subscribe(this::loadGroupsFromDBSuccessful, this::loadGroupsError);
    }

    private void loadGroupsFromDBSuccessful(ArrayList<Group> groups) {
        if (!isAttached()) {
            return;
        }

        getView().hideProgress();
        getView().setGroups(groups);
    }

    private void loadGroupsError(Throwable throwable) {
        Log.e(SharingPresenter.class.getSimpleName(), throwable.getMessage(), throwable);
    }
}
