package com.atmob.voiceai.module.result;

import android.net.Uri;
import android.os.Parcelable;

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

import com.atmob.app.lib.base.BaseViewModel;
import com.atmob.app.lib.livedata.SingleLiveEvent;
import com.atmob.common.logging.AtmobLog;
import com.atmob.common.runtime.ActivityUtil;
import com.atmob.common.runtime.ContextUtil;
import com.atmob.voiceai.R;
import com.atmob.voiceai.data.api.bean.UserVoiceBean;
import com.atmob.voiceai.data.api.bean.VoiceListBean;
import com.atmob.voiceai.data.api.response.VoiceListResponse;
import com.atmob.voiceai.data.consts.EventId;
import com.atmob.voiceai.data.repositories.VoiceAIRepository;
import com.atmob.voiceai.handlers.EventHandler;
import com.atmob.voiceai.utils.DateUtil;
import com.atmob.voiceai.utils.DownloadUtils;
import com.atmob.voiceai.utils.MediaStoreHelper;
import com.atmob.voiceai.utils.ScoringUtils;
import com.atmob.voiceai.utils.ShareUtils;
import com.atmob.voiceai.utils.ToastUtil;
import com.atmob.voiceai.utils.VoiceFileUtil;

import java.io.File;
import java.util.List;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

import javax.inject.Inject;

import atmob.okhttp3.OkHttpClient;
import atmob.reactivex.rxjava3.annotations.NonNull;
import atmob.reactivex.rxjava3.core.SingleObserver;
import atmob.reactivex.rxjava3.core.SingleSource;
import atmob.reactivex.rxjava3.disposables.Disposable;
import atmob.reactivex.rxjava3.functions.Action;
import atmob.reactivex.rxjava3.functions.Function;
import atmob.rxjava.utils.RxJavaUtil;
import dagger.hilt.android.lifecycle.HiltViewModel;

@HiltViewModel
public class VoiceResultViewModel extends BaseViewModel {


    private final VoiceAIRepository voiceAIRepository;
    private final MutableLiveData<Boolean> isPlay = new MutableLiveData<>();
    private final MutableLiveData<Long> totalDuration = new MutableLiveData<>();
    private final MutableLiveData<Long> currentDuration = new MutableLiveData<>();
    private final SingleLiveEvent<?> refreshAudioCurrentProgress = new SingleLiveEvent<>();
    private final MutableLiveData<List<VoiceListBean>> voiceList = new MutableLiveData<>();
    private final SingleLiveEvent<?> showScoringEvent = new SingleLiveEvent<>();
    private final MutableLiveData<UserVoiceBean> userVoiceBean = new MutableLiveData<>();
    private final MutableLiveData<Uri> voiceUri = new MutableLiveData<>();
    private final OkHttpClient okHttpClient;
    private boolean isSeekbarChanging;
    private Timer timer;

    private boolean downloadFileDisposable;

    private boolean isCanShowScoring;

    @Inject
    public VoiceResultViewModel(VoiceAIRepository voiceAIRepository, OkHttpClient okHttpClient) {
        this.voiceAIRepository = voiceAIRepository;
        this.okHttpClient = okHttpClient;
        refreshVoiceRecommendList();
        EventHandler.report(EventId.generateok_001);
        checkScoring();
    }

    public LiveData<Uri> getVoiceUri() {
        return voiceUri;
    }

    public LiveData<List<VoiceListBean>> getVoiceList() {
        return voiceList;
    }

    public LiveData<?> getShowScoringEvent() {
        return showScoringEvent;
    }

    public LiveData<Boolean> getIsPlay() {
        return isPlay;
    }

    public LiveData<?> getRefreshAudioCurrentProgress() {
        return refreshAudioCurrentProgress;
    }

    public LiveData<Long> getCurrentDuration() {
        return currentDuration;
    }

    public LiveData<Long> getTotalDuration() {
        return totalDuration;
    }

    public LiveData<UserVoiceBean> getResultBean() {
        return userVoiceBean;
    }


    private void checkScoring() {
        isCanShowScoring = ScoringUtils.checkShowScoring();
        if (!isCanShowScoring) {
            return;
        }
        addDisposable(RxJavaUtil.timer(5, TimeUnit.SECONDS, () -> {
            if (isCanShowScoring) {
                isCanShowScoring = false;
                showScoringEvent.call();
            }
        }));
    }

    public void setVoicePlay(boolean isPlay) {
        this.isPlay.setValue(isPlay);
    }

    public void setCurrentDuration(long duration) {
        if (duration >= 0) {
            currentDuration.setValue(duration);
        }
    }

    public void setTotalDuration(long duration) {
        if (duration >= 0) {
            totalDuration.setValue(duration);
        }
    }

    public void setSeekbarChanging(boolean seekbarChanging) {
        isSeekbarChanging = seekbarChanging;
    }


    public void startMediaTimer() {
        if (timer != null) {
            return;
        }
        timer = new Timer();
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                if (isSeekbarChanging) {
                    return;
                }
                refreshAudioCurrentProgress.postValue(null);
            }
        }, 0, 25);
    }

    public void onBackClick() {
        ActivityUtil.getTopActivity().finish();
    }

    private void refreshVoiceRecommendList() {
        voiceAIRepository.requestVoiceList("").subscribe(new SingleObserver<VoiceListResponse>() {
            @Override
            public void onSubscribe(@NonNull Disposable d) {
                addDisposable(d);
            }

            @Override
            public void onSuccess(@NonNull VoiceListResponse voiceListResponse) {
                voiceList.setValue(voiceListResponse.getVoiceList());
            }

            @Override
            public void onError(@NonNull Throwable e) {

            }
        });
    }

    public void setRecommendVoice(VoiceListBean voiceListBean) {
        voiceAIRepository.setRecommendClickBean(voiceListBean);
    }


    public void onSaveClick() {
        EventHandler.report(EventId.generateoksave_001);
        UserVoiceBean userVoiceBean = getResultBean().getValue();
        if (userVoiceBean == null) {
            return;
        }
        if (downloadFileDisposable) {
            return;
        }
        VoiceFileUtil.getVoiceFile(okHttpClient, userVoiceBean.getVoiceUrl())
                .map(file -> {
                    MediaStoreHelper.saveToSharedStorage(MediaStoreHelper.TYPE_AUDIO, file, file.getName());
                    return file;
                })
                .subscribe(new SingleObserver<File>() {
                    @Override
                    public void onSubscribe(@NonNull Disposable d) {
                        addDisposable(d);
                        downloadFileDisposable = true;
                    }

                    @Override
                    public void onSuccess(@NonNull File file) {
                        downloadFileDisposable = false;
                        ToastUtil.show(R.string.voice_save_success, ToastUtil.LENGTH_SHORT);
                        AtmobLog.d("VoiceResultViewModel", "onSuccess: " + file.getAbsolutePath());
                    }

                    @Override
                    public void onError(@NonNull Throwable e) {
                        downloadFileDisposable = false;
                        ToastUtil.show(R.string.voice_save_error, ToastUtil.LENGTH_SHORT);
                        AtmobLog.d("VoiceResultViewModel", "onError: " + e.getMessage());
                    }
                });
    }


    public void onShareClick() {
        EventHandler.report(EventId.generateokshare_001);
        UserVoiceBean userVoiceBean = getResultBean().getValue();
        if (userVoiceBean == null) {
            return;
        }
        if (downloadFileDisposable) {
            return;
        }
        VoiceFileUtil.getVoiceFile(okHttpClient, userVoiceBean.getVoiceUrl())
                .map(file -> {
                    ShareUtils.shareAudioFile(ActivityUtil.getTopActivity(), file);
                    return file;
                })
                .subscribe(new SingleObserver<File>() {
                    @Override
                    public void onSubscribe(@NonNull Disposable d) {
                        addDisposable(d);
                        downloadFileDisposable = true;
                    }

                    @Override
                    public void onSuccess(@NonNull File file) {
                        downloadFileDisposable = false;
                        AtmobLog.d("VoiceResultViewModel", "Share-onSuccess: " + file.getAbsolutePath());
                    }

                    @Override
                    public void onError(@NonNull Throwable e) {
                        downloadFileDisposable = false;
                        ToastUtil.show(R.string.voice_file_get_error, ToastUtil.LENGTH_SHORT);
                        AtmobLog.d("VoiceResultViewModel", "Share-onError: " + e.getMessage());
                    }
                });
    }


    public void setVoiceBean(UserVoiceBean userVoiceBean) {
        this.userVoiceBean.setValue(userVoiceBean);
        startDownloadVoice(userVoiceBean.getVoiceUrl());
    }

    private void startDownloadVoice(String voiceUrl) {
        VoiceFileUtil.getVoiceFile(okHttpClient, voiceUrl)
                .subscribe(new SingleObserver<File>() {
                    @Override
                    public void onSubscribe(@NonNull Disposable d) {
                        addDisposable(d);
                    }

                    @Override
                    public void onSuccess(@NonNull File file) {
                        voiceUri.setValue(Uri.fromFile(file));
                    }

                    @Override
                    public void onError(@NonNull Throwable e) {
                        voiceUri.setValue(Uri.parse(voiceUrl));
                    }
                });
    }


    @Override
    protected void onCleared() {
        super.onCleared();
        if (timer != null) {
            timer.cancel();
            timer = null;
        }
    }

    public void checkShowScoring() {
        if (isCanShowScoring) {
            isCanShowScoring = false;
            showScoringEvent.call();
        }
    }
}
