package com.example.iot_controlhost.base

import androidx.compose.material3.SnackbarHostState
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.blankj.utilcode.util.ActivityUtils
import com.example.iot_controlhost.utils.DialogUtil
import com.example.iot_controlhost.utils.PollingTask
import es.dmoral.toasty.Toasty
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext

open class BaseViewModel : ViewModel() {

    protected var pollingTask: PollingTask =
        PollingTask.getInstance(javaClass.simpleName) // 使用类名作为ID

    protected fun doInUIThread(task: () -> Unit) {
        viewModelScope.launch {
            withContext(Dispatchers.Main) {
                task()
            }
        }
    }

    protected fun <T> doInIoThreadThenUI(
        loadingTips: String = "正在加载中",
        showDialog: Boolean = true,
        onError: (Throwable) -> Unit = { },
        onIO: suspend () -> T,
        onUI: (T) -> Unit,
    ) {
        viewModelScope.launch {
            val result = runCatching {
                if (showDialog) {
                    DialogUtil.showLoadingDialog(ActivityUtils.getTopActivity(),loadingTips)
                }
                withContext(Dispatchers.IO) {
                    onIO()
                }
            }
            withContext(Dispatchers.Main) {
                if (showDialog) {
                    DialogUtil.hideLoadingDialog()
                }
                result.onSuccess { data ->
                    onUI(data)
                }.onFailure { exception ->
                    exception.printStackTrace()
                    onError(exception)
                    exception.message?.let {
                        Toasty.error(ActivityUtils.getTopActivity(),it).show()
                    }
                }
            }
        }
    }

    fun <T> doInIoThread(
        loadingTips: String = "正在加载中",
        showDialog: Boolean = true,
        onError: (Throwable) -> Unit = { },
        doInIO: suspend () -> T,
    ) {
        doInIoThreadThenUI(loadingTips, showDialog, onError, doInIO) { }
    }

    fun <T> doInIoThreadNoDialog(
        onError: (Throwable) -> Unit = { },
        task: suspend () -> T,
    ) {
        doInIoThread(showDialog = false, doInIO = task, onError = onError)
    }

    /**
     * 在IO线程中执行任务，可选择是否显示加载对话框
     */
    fun doInIoThreadWith(showLoading: Boolean,loadingTips: String,  function: suspend () -> Unit) {
        if (showLoading) {
            doInIoThread(loadingTips) { function() }
        } else {
            doInIoThreadNoDialog { function() }
        }
    }


    val scope = CoroutineScope(Dispatchers.IO)

    /**
     * 启动一个无限轮询任务
     *
     * @param pollingInterval 轮询间隔时间（单位：秒）
     * @param pollingTask 轮询任务的挂起函数
     */
    fun polling(intervalSeconds: Long, task: suspend () -> Unit) {
        scope.launch {
            while (true) {
                task()
                delay(intervalSeconds * 1000L) // 转换秒为毫秒
            }
        }
    }

    suspend fun delayPolling(delaySeconds: Long, intervalSeconds: Long, task: suspend () -> Unit) {
        delay(delaySeconds * 1000L)
        polling(intervalSeconds, task)
    }

}
