package com.zaojiao.app.feat.design.viewmodel

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.zaojiao.app.feat.design.UiState
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.cancel
import kotlinx.coroutines.launch

abstract class BaseViewModel<T>(
    private val autoInitial: Boolean = true,
    private val autoLoading: Boolean = true,
) : ViewModel() {
    private val _stateFlow = MutableStateFlow<UiState<T>>(UiState.Loading)
    val stateFlow: StateFlow<UiState<T>> get() = _stateFlow

    init {
        firstInit()
    }

    abstract suspend fun initData(): T

    protected fun firstInit() {
        if (autoInitial) {
            viewModelScope.launch {
                if (autoLoading) {
                    setLoading()
                }
                try {
                    val result = initData()
                    setSuccess(result)
                } catch (e: Throwable) {
                    e.printStackTrace()
                    setFailure(0)
                }
            }
        }
    }

    protected fun refresh() =
        viewModelScope.launch {
            try {
                val result = initData()
                setSuccess(result)
            } catch (e: Throwable) {
                setFailure(0)
            }
        }


    protected suspend fun setLoading() {
        _stateFlow.emit(UiState.Loading)
    }

    protected suspend fun setSuccess(data: T) {
        _stateFlow.emit(UiState.Success(data))
    }

    protected suspend fun setFailure(code: Int) {
        _stateFlow.emit(UiState.Failure(code))
    }
}