package com.jishisongfu.duobibi.auth

import android.app.Activity
import android.content.Context
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.jishisongfu.duobibi.data.api.AuthApi
import com.jishisongfu.duobibi.data.api.JverifyLoginRequest
import com.jishisongfu.duobibi.util.AuthPrefs
import dagger.hilt.android.lifecycle.HiltViewModel
import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch
import javax.inject.Inject

sealed interface BindPhoneState {
    data object Idle : BindPhoneState
    data class Working(val step: String) : BindPhoneState
    data class Success(val phone: String) : BindPhoneState
    data class Failed(val reason: String) : BindPhoneState
}

/**
 * 一键登录 → 绑定手机号 的状态机:
 *   checkEnable → preLogin → loginAuth → 后端 jverifyLogin → 持久化手机号
 *
 * 多比比 用账号占坑(后续做 CPS 归因 / 多设备),绑定成功只持久化 phone,不做云同步。
 * 任一步失败立刻进 Failed,带 reason 给 UI 显示。
 */
@HiltViewModel
class PhoneBindViewModel @Inject constructor(
    private val authApi: AuthApi,
    @ApplicationContext private val appCtx: Context,
) : ViewModel() {

    private val _state = MutableStateFlow<BindPhoneState>(BindPhoneState.Idle)
    val state: StateFlow<BindPhoneState> = _state.asStateFlow()

    fun bind(activity: Activity) {
        // 防重入:Working 状态下忽略新调用,避免连点触发并发 SDK 调用 + 运营商限频
        if (_state.value !is BindPhoneState.Idle) return
        viewModelScope.launch {
            _state.value = BindPhoneState.Working("检查网络环境...")
            if (!OneClickLogin.checkEnable(activity)) {
                _state.value = BindPhoneState.Failed(
                    "当前网络不支持一键登录。请打开蜂窝数据(WiFi 下需双通道)。",
                )
                return@launch
            }

            _state.value = BindPhoneState.Working("正在准备登录...")
            val pre = OneClickLogin.preLogin(activity)
            if (pre.isFailure) {
                _state.value = BindPhoneState.Failed(
                    "预取号失败:${pre.exceptionOrNull()?.message ?: "未知错误"}",
                )
                return@launch
            }

            _state.value = BindPhoneState.Working("等待运营商授权...")
            val auth = OneClickLogin.loginAuth(activity)
            if (auth.isFailure) {
                _state.value = BindPhoneState.Failed(
                    "授权失败:${auth.exceptionOrNull()?.message ?: "未知错误"}",
                )
                return@launch
            }
            val token = auth.getOrThrow()

            _state.value = BindPhoneState.Working("验证手机号...")
            try {
                val resp = authApi.jverifyLogin(
                    JverifyLoginRequest(loginToken = token.loginToken, operator = token.operator),
                )
                AuthPrefs.setBound(appCtx, resp.phone)
                _state.value = BindPhoneState.Success(resp.phone)
            } catch (e: Exception) {
                _state.value = BindPhoneState.Failed("后端验证失败:${e.message}")
            }
        }
    }

    fun reset() {
        _state.value = BindPhoneState.Idle
    }
}
