package com.narutohuo.xindazhou.common.ui

import android.app.Application
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.viewModelScope
import com.narutohuo.xindazhou.core.log.ILog
import kotlinx.coroutines.CoroutineExceptionHandler
import kotlinx.coroutines.launch

/**
 * ViewModel 基类
 * 
 * 提供统一的 ViewModel 功能，与其他平台（HarmonyOS/iOS）保持一致
 * 继承 AndroidViewModel，自动提供 Application 上下文
 * 
 * **核心功能**：
 * 1. 自动日志标签（tag）
 * 2. 安全的协程执行（自动捕获异常）
 * 3. 统一的错误处理
 * 4. 生命周期管理（onInit/onDestroy）
 * 
 * **使用方式**：
 * ```kotlin
 * class LoginViewModel(
 *     application: Application,
 *     private val authRepository: AuthRepository
 * ) : BaseViewModel(application) {
 *     
 *     private val _loginState = MutableStateFlow<LoginState>(LoginState.Idle)
 *     val loginState: StateFlow<LoginState> = _loginState
 *     
 *     fun login(mobile: String, password: String) {
 *         // 方式1：使用 safeLaunch（推荐，自动处理异常）
 *         safeLaunch {
 *             _loginState.value = LoginState.Loading
 *             val result = authRepository.login(mobile, password)
 *             result.onSuccess {
 *                 _loginState.value = LoginState.Success("登录成功")
 *             }.onFailure { e ->
 *                 _loginState.value = LoginState.Error(e.message ?: "登录失败")
 *             }
 *         }
 *     }
 * }
 * ```
 */
abstract class BaseViewModel(
    application: Application
) : AndroidViewModel(application) {
    
    /**
     * 日志标签（自动使用类名）
     */
    protected val tag: String
        get() = this::class.simpleName ?: "BaseViewModel"
    
    /**
     * ViewModel 初始化（可选）
     * 
     * 在 ViewModel 创建后调用，可用于初始化数据
     * 子类可重写此方法
     */
    open fun onInit() {
        // 子类可重写
    }
    
    /**
     * ViewModel 销毁（可选）
     * 
     * 在 ViewModel 被清除时调用，用于清理资源
     * 子类可重写此方法
     */
    override fun onCleared() {
        super.onCleared()
        onDestroy()
    }
    
    /**
     * ViewModel 销毁回调（可选）
     * 
     * 在 onCleared() 中调用，子类可重写此方法进行清理
     */
    protected open fun onDestroy() {
        // 子类可重写
    }
    
    /**
     * 处理错误（通用方法）
     * 
     * 提供统一的错误处理逻辑，子类可重写
     * 
     * @param throwable 异常对象
     * @param errorMessage 错误消息前缀（可选）
     * @return 处理后的错误消息
     */
    protected open fun handleError(throwable: Throwable, errorMessage: String = "操作失败"): String {
        val errorMsg = throwable.message ?: errorMessage
        ILog.e(tag, errorMsg, throwable)
        return errorMsg
    }
    
    /**
     * 获取 Application 上下文（便捷方法）
     */
    protected val applicationContext: android.content.Context
        get() = getApplication<Application>().applicationContext
    
    // ==================== 协程辅助方法 ====================
    
    /**
     * 安全的协程启动（自动捕获异常）
     * 
     * 自动处理协程中的异常，避免崩溃
     * 异常会通过 handleError() 方法统一处理
     * 
     * **使用示例**：
     * ```kotlin
     * safeLaunch {
     *     val result = repository.loadData()
     *     result.onSuccess { data ->
     *         _uiState.value = UiState.Success(data)
     *     }.onFailure { e ->
     *         _uiState.value = UiState.Error(handleError(e))
     *     }
     * }
     * ```
     * 
     * @param errorMessage 错误消息前缀（可选）
     * @param block 协程代码块
     */
    protected fun safeLaunch(
        errorMessage: String = "操作失败",
        block: suspend () -> Unit
    ) {
        viewModelScope.launch(
            CoroutineExceptionHandler { _, throwable ->
                handleError(throwable, errorMessage)
            }
        ) {
            try {
                block()
            } catch (e: Exception) {
                handleError(e, errorMessage)
            }
        }
    }
    
    /**
     * 执行网络请求（简化版）
     * 
     * 自动处理 Loading/Success/Error 状态，减少重复代码
     * 
     * **使用示例**：
     * ```kotlin
     * private val _loginState = MutableStateFlow<LoginState>(LoginState.Idle)
     * 
     * fun login(mobile: String, password: String) {
     *     executeRequest(
     *         stateFlow = _loginState,
     *         onLoading = { LoginState.Loading },
     *         onSuccess = { LoginState.Success("登录成功") },
     *         onError = { msg -> LoginState.Error(msg) },
     *         errorMessage = "登录失败"
     *     ) {
     *         authRepository.login(mobile, password)
     *     }
     * }
     * ```
     * 
     * @param stateFlow 状态流
     * @param onLoading 加载状态
     * @param onSuccess 成功状态
     * @param onError 错误状态（接收错误消息）
     * @param errorMessage 错误消息前缀
     * @param request 网络请求（返回 Result<T>）
     */
    protected fun <T, S> executeRequest(
        stateFlow: kotlinx.coroutines.flow.MutableStateFlow<S>,
        onLoading: () -> S,
        onSuccess: (T) -> S,
        onError: (String) -> S,
        errorMessage: String = "请求失败",
        request: suspend () -> Result<T>
    ) {
        viewModelScope.launch {
            try {
                stateFlow.value = onLoading()
                val result = request()
                result.onSuccess { data ->
                    stateFlow.value = onSuccess(data)
                }.onFailure { throwable ->
                    val errorMsg = handleError(throwable, errorMessage)
                    stateFlow.value = onError(errorMsg)
                }
            } catch (e: Exception) {
                val errorMsg = handleError(e, errorMessage)
                stateFlow.value = onError(errorMsg)
            }
        }
    }
}
