package com.p3.bewoplaner.page.profile;

import com.p3.bewoplaner.R;
import com.p3.bewoplaner.data.AppPrefsConstants;
import com.p3.bewoplaner.data.api.common.ErrorHandlingResponseConverter;
import com.p3.bewoplaner.data.api.services.ProfileService;
import com.p3.bewoplaner.data.prefs.StringPreference;
import com.p3.bewoplaner.di.scopes.ActivityScope;
import com.p3.bewoplaner.model.User;
import com.p3.bewoplaner.page.mvp.MVPAbstractPresenter;
import com.p3.bewoplaner.utils.SystemUtils;
import com.p3.bewoplaner.utils.rx.RxUtils;

import android.net.Uri;
import android.support.annotation.NonNull;

import java.io.File;

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

import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.RequestBody;
import rx.Subscription;

/**
 * Created by imarneanu on 2/22/17.
 */
@ActivityScope
class ProfilePresenter extends MVPAbstractPresenter<ProfileView> implements ProfileView.Callback {

    @Inject
    SystemUtils mSystemUtils;

    @Inject
    ProfileService mProfileService;

    @Inject
    @SuppressWarnings("WeakerAccess")
    @Named(AppPrefsConstants.LOGIN_TOKEN)
    StringPreference mToken;

    @Inject
    ProfilePresenter() {
    }

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

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

    /**
     * Get logged in user profile.
     */

    @Override
    public void getProfile() {
        Subscription subscription = mProfileService.getProfile()
                .compose(RxUtils.provideDefaultTransformer())
                .flatMap(new ErrorHandlingResponseConverter<>())
                .map(profileResponse -> profileResponse.response.user)
                .subscribe(this::getProfileSuccess, this::profileError);
        addSubscription(subscription);
    }

    /**
     * Update phoneNumber for the logged in user.
     */

    @Override
    public void updateProfile(String phoneNumber) {
        Subscription subscription = mProfileService.updateProfile(phoneNumber)
                .compose(RxUtils.provideDefaultTransformer())
                .flatMap(new ErrorHandlingResponseConverter<>())
                .map(profileResponse -> profileResponse.response.user)
                .subscribe(this::profileSuccess, this::profileError);
        addSubscription(subscription);
    }

    /**
     * Upload image for the current user.
     */

    @Override
    public void uploadImage(Uri uri) {
        if (mSystemUtils.isNetworkUnavailable()) {
            getView().showError(R.string.error_no_internet_connection);
            return;
        }

        File file = getView().getFile(uri);
        RequestBody requestBody = RequestBody.create(MediaType.parse("image/*"), file);
        MultipartBody.Part part = MultipartBody.Part.createFormData("picture", file.getName(), requestBody);
        final Subscription subscription = mProfileService.uploadProfileImage(part)
                .compose(RxUtils.provideDefaultTransformer())
                .map(uploadImageResponse -> uploadImageResponse.response.picture)
                .subscribe(this::uploadImageSuccess, this::profileError);
        addSubscription(subscription);
    }

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

    private void getProfileSuccess(User user) {
        getView().setProfile(user);
    }

    private void profileSuccess(User user) {
        getView().setProfile(user);
        getView().showError(R.string.profile_updated);
    }

    private void uploadImageSuccess(String imageResponse) {
        getView().refreshImage(imageResponse);
        getView().showError(R.string.profile_updated);
    }

}
