package com.adealink.weparty.image.viewmodel

import androidx.lifecycle.LiveData
import com.adealink.frame.base.IError
import com.adealink.frame.base.Rlt
import com.adealink.frame.download.listener.TaskListener
import com.adealink.frame.download.task.Task
import com.adealink.frame.log.Log
import com.adealink.frame.mvvm.livedata.OnceMutableLiveData
import com.adealink.frame.mvvm.viewmodel.BaseViewModel
import com.adealink.frame.storage.file.WeFile
import com.adealink.frame.storage.file.getCacheFilePathByUrl
import com.adealink.frame.storageService
import com.adealink.frame.util.md5
import com.adealink.weparty.App
import com.adealink.weparty.image.data.TAG_VIDEO_DOWNLOAD
import kotlinx.coroutines.launch
import kotlinx.coroutines.suspendCancellableCoroutine
import kotlin.coroutines.resume

class VideoViewModel : BaseViewModel() {

    fun downloadVideo(url: String): LiveData<Rlt<WeFile>> {
        val liveData = OnceMutableLiveData<Rlt<WeFile>>()
        viewModelScope.launch {
            liveData.send(download(url))
        }
        return liveData
    }

    private suspend fun download(url: String): Rlt<WeFile> {
        return suspendCancellableCoroutine { continuation ->
            addDownloadTask(url,
                {
                    if (continuation.isActive) {
                        continuation.resume(Rlt.Success(it))
                    }
                },
                {
                    if (continuation.isActive) {
                        continuation.resume(Rlt.Failed(it))
                    }
                })
        }
    }

    private fun addDownloadTask(
        url: String,
        success: ((path: WeFile) -> Unit)? = null,
        failed: ((error: IError) -> Unit)? = null,
    ) {
        val savePath = getCacheFilePathByUrl(url)
        val file = storageService.file.createWeFile(savePath)
        if (file.exists()) {
            success?.invoke(file)
            return
        }

        val taskId = url.md5()
        val task = Task(taskId, url, savePath)
        Log.d(
            TAG_VIDEO_DOWNLOAD,
            "addDownloadTask, start download, url:$url, task:$task"
        )
        task.listeners.add(object : TaskListener {

            override fun onFinished(task: Task) {
                super.onFinished(task)
                success?.invoke(file)
                Log.d(
                    TAG_VIDEO_DOWNLOAD,
                    "addDownloadTask, download success, task:$task"
                )
            }

            override fun onError(task: Task, error: IError) {
                super.onError(task, error)
                failed?.invoke(error)
                Log.e(
                    TAG_VIDEO_DOWNLOAD,
                    "addDownloadTask, task:$task, error:$error"
                )
            }

        })
        App.instance.downloadService.addTask(task)
    }

}