package org.mercury_im.messenger.android.crypto.ikey;

import android.graphics.Bitmap;

import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;

import org.jivesoftware.smackx.ox.OpenPgpSecretKeyBackupPassphrase;
import org.mercury_im.messenger.android.MercuryImApplication;
import org.mercury_im.messenger.android.ui.base.MercuryAndroidViewModel;
import org.mercury_im.messenger.android.util.QrCodeGenerator;
import org.mercury_im.messenger.core.SchedulersFacade;
import org.mercury_im.messenger.core.crypto.OpenPgpSecretKeyBackupPassphraseGenerator;
import org.mercury_im.messenger.core.util.Optional;
import org.mercury_im.messenger.core.viewmodel.ikey.IkeySecretKeyBackupCreationViewModel;

import java.util.UUID;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.inject.Inject;

import io.reactivex.Observable;

public class AndroidIkeyBackupCreationViewModel extends ViewModel implements MercuryAndroidViewModel<IkeySecretKeyBackupCreationViewModel> {

    private static final Logger LOGGER = Logger.getLogger(AndroidIkeyBackupCreationViewModel.class.getName());

    MutableLiveData<OpenPgpSecretKeyBackupPassphrase> passphrase = new MutableLiveData<>();
    MutableLiveData<Bitmap> passphraseAsQrCode = new MutableLiveData<>();

    @Inject
    IkeySecretKeyBackupCreationViewModel commonViewModel;

    @Inject
    OpenPgpSecretKeyBackupPassphraseGenerator passphraseGenerator;

    @Inject
    SchedulersFacade schedulers;

    public AndroidIkeyBackupCreationViewModel() {
        MercuryImApplication.getApplication().getAppComponent().inject(this);
    }

    public void initialize(UUID accountId) {
        getCommonViewModel().setAccountId(accountId);

        Observable<Optional<OpenPgpSecretKeyBackupPassphrase>> passphraseObservable =
                getCommonViewModel().getPassphrase();
                //Observable.just(new Optional<>(passphraseGenerator.generateBackupPassphrase()));

        addDisposable(passphraseObservable
                .subscribeOn(schedulers.getIoScheduler())
                .observeOn(schedulers.getUiScheduler())
                .filter(Optional::isPresent)
                .map(Optional::getItem)
                .subscribe(
                        passphrase::setValue,
                        e -> LOGGER.log(Level.SEVERE, "Error subscribing to passphrase", e)));

        addDisposable(passphraseObservable
                .filter(Optional::isPresent)
                .map(Optional::getItem)
                .map(pass -> QrCodeGenerator.generateBarcode(pass.toString()))
                .subscribeOn(schedulers.getIoScheduler())
                .observeOn(schedulers.getUiScheduler())
                .subscribe(passphraseAsQrCode::setValue,
                        e -> LOGGER.log(Level.SEVERE, "Error subscribing to passphrase QR code", e)));
    }

    public LiveData<OpenPgpSecretKeyBackupPassphrase> getPassphrase() {
        return passphrase;
    }

    public LiveData<Bitmap> getPassphraseAsQrCode() {
        return passphraseAsQrCode;
    }

    @Override
    public IkeySecretKeyBackupCreationViewModel getCommonViewModel() {
        return commonViewModel;
    }

    public void uploadBackup() {
        addDisposable(getCommonViewModel().createBackup()
                .compose(schedulers.executeUiSafeCompletable())
                .subscribe(() -> LOGGER.log(Level.INFO, "Successfully uploaded ikey backup."),
                        e -> LOGGER.log(Level.INFO, "Error uploading ikey backup:", e)));
    }
}
