package de.beyondsoft.ownchat.page.profile;

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.services.ProfileService;
import de.beyondsoft.ownchat.data.prefs.LongPreference;
import de.beyondsoft.ownchat.data.prefs.StringPreference;
import de.beyondsoft.ownchat.di.scopes.ActivityScope;
import de.beyondsoft.ownchat.model.User;
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 android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.support.annotation.NonNull;
import android.view.View;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

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
    @Named(AppPrefsConstants.UPLOAD_MAX_SIZE)
    LongPreference mUploadMaxSizePreference;

    @Inject
    Context mContext;

    @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 = FileUtils.getFile(mContext, uri);
        String mimeType = FileUtils.getMimeType(file);

        if(mUploadMaxSizePreference.get() > 0 && file.length() > mUploadMaxSizePreference.get()) {
            getView().showError(R.string.error_file_is_too_large);
            return;
        }

        if(mimeType != null && (mimeType.equals(Constants.MIME_TYPE_JPEG) || mimeType.equals(Constants.MIME_TYPE_PNG)) && (file.length() > (1000L * 1024L))) {
            FileUtils.clearTmpFilesDir(mContext);

            file = FileUtils.scaleImageDown(file, mContext);
        }

        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);
    }
}
