package com.gamedog.vididin.manager

import com.ama.core.architecture.util.AndroidUtil
import com.ama.core.architecture.util.DateUtil
import com.ama.core.architecture.util.DeviceUtil
import com.ama.core.architecture.util.MD5Util
import com.ama.core.architecture.util.NetUtil
import com.ama.core.architecture.util.SpUtil
import com.ama.core.architecture.util.eventbus.NotifyMan
import com.gamedog.statisticreporter.StatisticUtil
import com.gamedog.vididin.VidiConst
import com.gamedog.vididin.VididinEvents
import com.gamedog.vididin.beans.RECORD_CASH_WITHDRAW
import com.gamedog.vididin.beans.RecordCash
import com.gamedog.vididin.beans.req.PayInitReq
import com.gamedog.vididin.beans.req.PayoutCheckReq
import com.gamedog.vididin.beans.req.PayoutReq
import com.gamedog.vididin.beans.resp.PayInit
import com.gamedog.vididin.beans.resp.PayoutData
import com.gamedog.vididin.core.login.login.AccountManager
import com.gamedog.vididin.manager.WithdrawManager.Companion.STATE_NEED_WATCH_AD
import com.gamedog.vididin.netbase.NetworkUtil
import com.gamedog.vididin.netbase.Result
import com.viddin.videos.free.R
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch


class WithdrawManager private constructor() {

    private val mBgScope = CoroutineScope(SupervisorJob() + Dispatchers.IO)



    private val mWithdrawItemList: MutableList<WithdrawItem> by lazy {
        val itemList = SpUtil.instance().getList<WithdrawItem>(SpUtil.KEY_WITHDRAW_ITEM_LIST).toMutableList()
        if (itemList.isEmpty()) {
            itemList.addAll(generateItemList())
            saveInfos2Sp(itemList)
        }
        itemList
    }

    companion object {
        const val EACH_SUB_ITEM_CASH_NUM: Double = 1.0

         //----------------------- FROM pagsmile.proto ------------------------------
        // init接口 status
        // 1可提现 2:条件未达成 3:已提现, 4:禁止提现, 5:提现中
        const val INIT_OK = 1
        const val ERROR_COMMON_UNKNOW = 999
        const val ERROR_INIT_NOT_REACH_CONDITION = 2
        const val ERROR_INIT_ALREADY_WITHDRAWED = 3
        const val ERROR_INIT_FORBID = 4
        const val ERROR_INIT_WITHDRAWING = 5
        // init接口 服务器 error 字段
        // 0成功，1失败，2签名验证失败，3客户端版本过低，4 ts长度错误
        const val ERROR_INIT_FAILED_UNKNOW = ERROR_COMMON_UNKNOW
        const val ERROR_INIT_APP_VERSION_LOW = 3 + 10
        /* payout接口： 错误码，
        0成功，1失败，2签名验证失败，3客户端版本过低，4uuid错误，5所在地国家或地区不在提现限制内，6提现金额不符对应的产品id，7提现产品id不对，8达到提现金额限制，9提现次数超过限制，10今日没有提现机会，11提现账号达到次数限制，12身份审核条件不满足，不能提现，13巴西提现参数 document_type 错误，
        14巴西提现参数 document_id 错误，15 巴西提现参数 AccountType 错误，16 巴西提现参数 Name 错误，17巴西提现参数 Account 和  DocumentId 不同，18巴西提现参数account_type为CPF时 对应的 account 错误，19巴西提现参数account_type为CNPJ时 对应的 account 错误，20巴西提现参数 account_type 错误，
        21巴西提现参数 document_type 错误，22巴西提现参数account_type为CPF时 对应的 document_id 错误，23巴西提现参数account_type为CNPJ时 对应的 document_id 错误，24 ts长度错误，25 没提0.1就提现其它的
         */
        const val ERROR_PAYOUT_UNKNOW = 1 + 20
        const val ERROR_PAYOUT_APP_VERSION_LOW = 3 + 20
        const val ERROR_PAYOUT_COUNTRY_RESTRICTION = 5 + 20
        const val ERROR_PAYOUT_REACH_TOTAL_LIMIT = 8 + 20
        const val ERROR_PAYOUT_REACH_TIMES_LIMIT = 9 + 20
        const val ERROR_PAYOUT_TODAY_NO_CHANCE = 10 + 20
        const val ERROR_PAYOUT_ACCOUNT_REACH_TIMES_LIMIT = 11 + 20
        const val ERROR_PAYOUT_ACCOUNT_INVALID = 18 + 20
        const val ERROR_PAYOUT_USER_IDENTITY_LIMIT = 12 + 20
        const val ERROR_PAYOUT_MUST_WITHDRAW01_FIRST = 25 + 20







        // subBean 状态
        const val STATE_NEED_WATCH_AD: Int = 0
        const val STATE_COULD_WITHDRAW: Int = 1
        const val STATE_WITHDRAWING: Int = 2
        const val STATE_HAS_WITHDRAWED: Int = 3

        //  提现交易状态  提现状态 0: 未启动 1:提现中,2:提现成功,3:提现失败
        const val TRANSACTION_STATE_UNSTART : Int = 0
        const val TRANSACTION_STATE_ONGOING : Int = 1
        const val TRANSACTION_STATE_SUCCESS : Int = 2
        const val TRANSACTION_STATE_FAIL : Int = 3



        @Volatile
        private var instance: WithdrawManager? = null
        fun instance(): WithdrawManager {
            return instance ?: synchronized(this) {
                instance ?: WithdrawManager().also {
                    instance = it
                }
            }
        }
    }

    init {
        loopCheckTransactionState()
    }



    private fun generateItemList(): MutableList<WithdrawItem> {
        val itemList = mutableListOf<WithdrawItem>()
        itemList.add(WithdrawItem(0, 0.1, isBigWithDraw = false))
        itemList.add(WithdrawItem(1, 10.0, AndroidUtil.randomInt(50, 70), generateSubItemList(10.0)))
        itemList.add(WithdrawItem(2, 20.0, AndroidUtil.randomInt(50, 70), generateSubItemList(20.0)))
        itemList.add(WithdrawItem(3, 50.0, AndroidUtil.randomInt(50, 70), generateSubItemList(50.0)))
        itemList.add(WithdrawItem(4, 100.0, AndroidUtil.randomInt(50, 70), generateSubItemList(100.0)))
        itemList.add(WithdrawItem(5, 300.0, AndroidUtil.randomInt(50, 70), generateSubItemList(300.0)))
        return itemList
    }

    private fun generateSubItemList(totalCashInItem: Double): List<WithdrawSubItem> {
        val subItemList = mutableListOf<WithdrawSubItem>()
        val subItemCount: Int = (totalCashInItem/EACH_SUB_ITEM_CASH_NUM).toInt()

        for (i in 0..subItemCount-1) {
            val initProgress = AndroidUtil.randomInt(50, 70)
            subItemList.add(WithdrawSubItem(i, EACH_SUB_ITEM_CASH_NUM, initProgress, initProgress, 0.0))
        }
        return subItemList
    }

    private fun saveInfos2Sp(itemList: MutableList<WithdrawItem>) {
        SpUtil.instance().putList(SpUtil.KEY_WITHDRAW_ITEM_LIST, itemList)
    }


    fun getItem(itemIndex: Int): WithdrawItem {
        return mWithdrawItemList[itemIndex]
    }


    fun getHasWithdrawSuccessCashCount(): Double {
        return RecordsManager.instance().getHasWithdrawSuccessCashCount()
    }

    fun addAdEarnForSubBean(itemIndex: Int, selectedSubIndex: Int, earnMoneyNum: Double) : Boolean {
        if (itemIndex >= 0 && itemIndex < mWithdrawItemList.size) {
            try {
                val subBean = mWithdrawItemList[itemIndex].subItemList[selectedSubIndex]
                subBean.hasEarnMoneyByAd += earnMoneyNum * 5 // dollar 2 bariz
                calculateSubBeanProgress(subBean)  //传入 itembean 更新 selectedIndex为下一个
                saveInfos2Sp(mWithdrawItemList)
                notifyProgressUpdated(subBean)
                return true
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }

        return false
    }

    private fun notifyProgressUpdated(subBean: WithdrawSubItem) {
        NotifyMan.instance().sendEvent(VididinEvents.EVENT_WITHDRAW_SUB_ITEM_PROGRESS_UPDATED,
            NotifyMan.NotifyData(subBean.dayIndex))
    }

    private fun notifySelectedSubBeanChanged(subBean: WithdrawSubItem) {
        NotifyMan.instance().sendEvent(VididinEvents.EVENT_WITHDRAW_SELECTED_SUB_ITEM_CHANGED, NotifyMan.NotifyData(subBean.dayIndex))
    }

    private fun notifyItemListChanged() {
        NotifyMan.instance().sendEvent(VididinEvents.EVENT_WITHDRAW_ITEM_LIST_CHANGED, null)
    }

    private fun notifyWithdrawResult(withdrawRecord: RecordCash) {
        NotifyMan.instance().sendEvent(VididinEvents.EVENT_WITHDRAW_RESULT_UPDATED, NotifyMan.NotifyData(withdrawRecord))
    }


    private fun calculateSubBeanProgress(subBean: WithdrawSubItem) {
        val needEarnProgress = 100 - subBean.startAdProgress
        if (subBean.hasEarnMoneyByAd >= subBean.cashTotal) {
            subBean.currentAdProgress = 100
            // update state
            if (subBean.withdrawState == STATE_NEED_WATCH_AD) {
                subBean.withdrawState = STATE_COULD_WITHDRAW
            }
        } else {
            val newProgress = subBean.startAdProgress + (needEarnProgress * (subBean.hasEarnMoneyByAd / subBean.cashTotal)).toInt()
            subBean.currentAdProgress = if (newProgress >= 100) 100 else newProgress
        }
    }

    fun updateSubBeanState(subBean: WithdrawSubItem, newState: Int) {
        subBean.withdrawState = newState
        saveInfos2Sp(mWithdrawItemList)
    }

    fun startItem(curItem: WithdrawItem) {
        if (curItem.startMs <= 0L) {
            curItem.startMs = DateUtil.getCurTimeMs() - (if (curItem.totalCashNum == 50.0) 24 * 3600000 * 4 else 0)
            saveInfos2Sp(mWithdrawItemList)
        }
    }

    fun updateRecordHasNotifyState(operationUUID: String) {
        RecordsManager.instance().updateRecordHasNotifyState(operationUUID)
    }

    fun saveNewWithdrawRecord(newRecord: RecordCash) {
        RecordsManager.instance().saveNewWithdrawRecord(newRecord)
    }


    private fun checkIfItemFinishAndReset(itemIndex: Int) {
        var needReset = false
        if (itemIndex == 0) {
            needReset = true
        } else {
            var allSubItemFinish = true
            mWithdrawItemList[itemIndex].subItemList.forEach {
                if (it.withdrawState != STATE_HAS_WITHDRAWED) {
                    allSubItemFinish = false
                    return@forEach
                }
            }
            needReset = allSubItemFinish
        }

        if (needReset) {
            resetWithdrawItem(itemIndex)
        }
    }

    private fun resetWithdrawItem(itemIndex: Int) {
        val needResetItem = mWithdrawItemList[itemIndex]
        needResetItem.apply {
            totalProgress = 0
            startMs = 0L
            hasStarted = false
            loopIndex++

            subItemList.forEach { subItem ->
                subItem.apply {
                    currentAdProgress = startAdProgress
                    hasEarnMoneyByAd = 0.0
                    withdrawState = STATE_NEED_WATCH_AD
                }
            }
        }

        notifyItemListChanged()
    }


    fun getClonedRecordList(): List<RecordCash> {
        return RecordsManager.instance().getWithdrawRecordList()
    }

    private fun getOngoingRecordList(): List<RecordCash> {
        return RecordsManager.instance().getOngoingRecordList()
    }


    private fun loopCheckTransactionState() {
        val ongoingList = getOngoingRecordList()
        if (ongoingList.isNotEmpty()) {
            try {
                ongoingList.forEachIndexed { index, record ->
                    mBgScope.launch {
                        if (!record.payOutReplyNo.isEmpty()) {
                            requestCheck(record)
                        }
                    }
                }
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }
    }

    private suspend fun requestCheck(withdrawRecord: RecordCash) {
        val recordNo = withdrawRecord.payOutReplyNo
        val checkReqParam = applyInitFields(PayoutCheckReq()).apply {
            record_no = recordNo
        }

        val checkReqResult = NetworkUtil.callApi {
            NetworkUtil.apiservice().withdrawCheck(checkReqParam)
        }

        when (checkReqResult) {
            is Result.Loading -> {
            }

            is Result.Error -> {
            }

            is Result.Success -> {
                val checkResult = checkReqResult.data.data
                var failedType = -1
                when (checkResult?.error) {
                    0 -> {
                        when (checkResult.status) {
                            //  提现状态 1:提现中,2:提现成功,3:提现失败
                            1 -> {
                                delay(10000)
                                loopCheckTransactionState()
                            }
                            2 -> {
                                handleLoopCheckWithdrawSuccess(withdrawRecord)
                            }
                            3 -> {
                                failedType = ERROR_COMMON_UNKNOW
                            }
                        }
                    }

                    1 -> {
                        failedType = ERROR_COMMON_UNKNOW
                    }

                    3 -> {
                        failedType = ERROR_PAYOUT_APP_VERSION_LOW
                    }
                }

                if (failedType > 0) {
                    handleWithdrawFailed(failedType, withdrawRecord)
                }
            }

        }
    }


    fun getFailHintStrRes(failType: Int) : Int {
        var failTextRes = R.string.withdraw_normal_fail
        when (failType) {
            // 仅仅显示三种
            ERROR_PAYOUT_ACCOUNT_INVALID -> {
                failTextRes = R.string.withdraw_account_invalid
            }


            ERROR_PAYOUT_REACH_TOTAL_LIMIT, ERROR_PAYOUT_TODAY_NO_CHANCE,
            ERROR_PAYOUT_ACCOUNT_REACH_TIMES_LIMIT, ERROR_PAYOUT_REACH_TIMES_LIMIT -> {
                failTextRes = R.string.withdraw_fail_reach_times_limit
            }

            else -> {
                failTextRes = R.string.withdraw_normal_fail
            }


            /*ERROR_COMMON_UNKNOW -> {
                failTextRes = R.string.withdraw_normal_fail
            }

            ERROR_INIT_NOT_REACH_CONDITION -> {
                failTextRes = R.string.withdraw_fail_not_reach_condition
            }

            ERROR_INIT_ALREADY_WITHDRAWED -> {
                failTextRes = R.string.withdraw_fail_already_withdraw
            }

            ERROR_INIT_FORBID -> {
                failTextRes = R.string.withdraw_fail_forbidden
            }

            ERROR_INIT_WITHDRAWING -> {
                failTextRes = R.string.withdraw_fail_withdrawing
            }

            ERROR_INIT_FAILED_UNKNOW -> {
                failTextRes = R.string.withdraw_normal_fail
            }

            ERROR_INIT_APP_VERSION_LOW -> {
                failTextRes = R.string.withdraw_fail_version_toolow
            }

            ERROR_PAYOUT_UNKNOW -> {
                failTextRes = R.string.withdraw_normal_fail
            }

            ERROR_PAYOUT_APP_VERSION_LOW -> {
                failTextRes = R.string.withdraw_fail_version_toolow
            }

            ERROR_PAYOUT_COUNTRY_RESTRICTION -> {
                failTextRes = R.string.withdraw_fail_country_restriction
            }

            ERROR_PAYOUT_REACH_TOTAL_LIMIT -> {
                failTextRes = R.string.withdraw_fail_reach_amount_limit
            }

            ERROR_PAYOUT_REACH_TIMES_LIMIT -> {
                failTextRes = R.string.withdraw_fail_reach_times_limit
            }

            ERROR_PAYOUT_TODAY_NO_CHANCE -> {
                failTextRes = R.string.withdraw_fail_today_no_chance
            }

            ERROR_PAYOUT_ACCOUNT_REACH_TIMES_LIMIT -> {
                failTextRes = R.string.withdraw_account_times_limit
            }

            ERROR_PAYOUT_ACCOUNT_INVALID -> {
                failTextRes = R.string.withdraw_account_invalid
            }

            ERROR_PAYOUT_USER_IDENTITY_LIMIT -> {
                failTextRes = R.string.withdraw_fail_user_identity_limit
            }

            ERROR_PAYOUT_MUST_WITHDRAW01_FIRST -> {
                failTextRes = R.string.withdraw_fail_must_withdraw_01_first
            }*/
        }
        return  failTextRes
    }


    fun <T : PayInitReq> applyInitFields(dataBean: T): T {
        dataBean.apply {
            platform = "Android"
            deviceid = DeviceUtil.generateDeviceId()
            version = AndroidUtil.getAppVersionInfo()
            ip = NetUtil.getLocalIpAddress()
            ts = (System.currentTimeMillis()/1000).toString()
            val signOrigin = "${VidiConst.WITHDRAW_MD5KEY}platform=${platform}deviceid=${deviceid}version=${version}ip=${ip}ts=$ts"
            sign = MD5Util.md5ForWithDraw(signOrigin)
        }
        return dataBean
    }



    fun getItemProgress(itemIndex: Int): Double {
        var itemProgress = 0.0

        if (itemIndex in 0..mWithdrawItemList.size-1) {
            val curItem = mWithdrawItemList[itemIndex]
            val userCashTotal = AccountManager.getCash()
            if (curItem.hasStarted) {
                return 1.0
            } else {
                itemProgress = if ((userCashTotal / curItem.totalCashNum) > 1.0) 1.0 else userCashTotal / curItem.totalCashNum
            }
        }

        return itemProgress
    }

    fun setItemStarted(itemIndex: Int) {
        if (itemIndex in 0..mWithdrawItemList.size-1) {
            val curItem = mWithdrawItemList[itemIndex]
            if (!curItem.hasStarted) {
                curItem.hasStarted = true
                curItem.startMs = System.currentTimeMillis()
                AccountManager.adjustCash(-1 * curItem.totalCashNum)
                saveInfos2Sp(mWithdrawItemList)
                notifyItemListChanged()
            }
        }
    }





    // ------------------------------- Withdraw Init and Payout -----------------------------------
    fun startWithdrawReal(payCashNum: Double, withdrawItemId: Int, withdrawSubItemId: Int, payItemLoopIndex: Int) {
        mBgScope.launch {

            val withdrawRecord = RecordCash(RECORD_CASH_WITHDRAW, payCashNum).apply {
                uuid = AndroidUtil.randomUUid()
                withdrawState = TRANSACTION_STATE_ONGOING
                withdrawItemIndex = withdrawItemId
                withdrawItemSubIndex = withdrawSubItemId
                withdrawItemLoopIndex = payItemLoopIndex
            }
            saveNewWithdrawRecord(withdrawRecord)

            val initReqParam = applyInitFields( PayInitReq())
            val initReqResult = NetworkUtil.callApi {
                NetworkUtil.apiservice().withdrawInit(initReqParam)
            }
            when (initReqResult) {
                is Result.Loading -> {

                }
                is Result.Error -> {
                    handleWithdrawFailed(ERROR_COMMON_UNKNOW, withdrawRecord)
                }
                is Result.Success<PayInit> -> {
                    val initResp = initReqResult.data.data
                    initResp?.let {
                        var failType = 0
                        if (it.error == 0 && !it.uuid.isNullOrEmpty() && !it.items.isNullOrEmpty()) {
                            val isSmallWithdraw = withdrawRecord.amountNum <= VidiConst.WITHDRAW_SMALL_NUM
                            val withDrawItem = it.items?.get(if (isSmallWithdraw) 0 else 1)!!
                            if (withDrawItem.status == INIT_OK) {
                                withdrawRecord.withdrawInitUUID = it.uuid!!
                                val shouldUserPayItemIndex = if (isSmallWithdraw) 0 else 1
                                if (shouldUserPayItemIndex < it.items!!.size) {
                                    withdrawRecord.payInitItemId = it.items?.get(shouldUserPayItemIndex)?.id!!
                                }

                                // start payOut
                                requestPayout(withdrawRecord)
                            } else {
                                failType = withDrawItem.status
                            }
                        } else {
                            // 0成功，1失败，2签名验证失败，3客户端版本过低，4 ts长度错误
                            failType = it.error + 10
                        }

                        if (failType > 0) {
                            handleWithdrawFailed(failType, withdrawRecord)
                        }
                    }
                }
            }
        }
    }


    private fun requestPayout(withdrawRecord: RecordCash) {
        mBgScope.launch {
            val payoutReqParam = applyInitFields(PayoutReq()).apply {
                val bankAccount = AccountManager.getAccount().bankInfo?.bankAccount
                val accountType = "CPF"

                account = bankAccount
                item_id = withdrawRecord.payInitItemId
                amount = withdrawRecord.amountNum.toString()
                additional_remark = "communnyboneycashmoneyrewardfastrealgame"
                uuid = withdrawRecord.withdrawInitUUID
                account_type = accountType
                document_type = accountType
                document_id = bankAccount
                name = "CapyBucks"
                clientName = AndroidUtil.getPackageId()


                dataAdjust.gps_adid = "gaid"
                dataAdjust.android_id = "androidid"
                dataAdjust.adid = "adid"
                dataAdjust.user_agent = "GetUerAgent"
                dataAdjust.price = amount
                dataAdjust.currency = "USD"

                dataShuShu.gps_gaid = "gaid"
                dataShuShu.android_id = "androidid"
                dataShuShu.adid = "adid"
                dataShuShu.user_agent = "GetUerAgent"
                dataShuShu.price = amount
                dataShuShu.currency = "USD"
                dataShuShu.payment_method = "Pix"
                dataShuShu.payment_type = accountType
                dataShuShu.payment_number = account
                dataShuShu.iap_name = "100br"
                dataShuShu.gamecoin_number = "100"
                dataShuShu.gamecoin_type = "gold"
                dataShuShu.ss_account_id = "GetSSAccountId"
                dataShuShu.ss_distinct_id = "GetSSDistinctId"
                dataShuShu.ss_super_properties =  "GetSSSuper Properties"
            }

            val payoutReqResult = NetworkUtil.callApi {
                NetworkUtil.apiservice().withdrawPayout(payoutReqParam)
            }

            when (payoutReqResult) {
                Result.Loading -> {

                }

                is Result.Error -> {
                    handleWithdrawFailed(ERROR_COMMON_UNKNOW, withdrawRecord)
                }

                is Result.Success<PayoutData> -> {
                    val payoutResultData = payoutReqResult.data.data

                    payoutResultData?.let {
                        withdrawRecord.payOutReplyId = payoutResultData.id?:""
                        withdrawRecord.payOutReplyNo = payoutResultData.record_no

                        if (payoutResultData.error == 0) {
                            // 1 更新 record并保存
                            RecordsManager.instance().updateCashRecord(withdrawRecord)
                            // 2 loop check 最终结果
                            loopCheckTransactionState()
                        } else {
                            var failType: Int? = 0
                            /* 错误码，
                            0成功，1失败，2签名验证失败，3客户端版本过低，4uuid错误，5所在地国家或地区不在提现限制内，6提现金额不符对应的产品id，7提现产品id不对，8达到提现金额限制，9提现次数超过限制，10今日没有提现机会，11提现账号达到次数限制，12身份审核条件不满足，不能提现，13巴西提现参数 document_type 错误，
                            14巴西提现参数 document_id 错误，15 巴西提现参数 AccountType 错误，16 巴西提现参数 Name 错误，17巴西提现参数 Account 和  DocumentId 不同，18巴西提现参数account_type为CPF时 对应的 account 错误，19巴西提现参数account_type为CNPJ时 对应的 account 错误，20巴西提现参数 account_type 错误，
                            21巴西提现参数 document_type 错误，22巴西提现参数account_type为CPF时 对应的 document_id 错误，23巴西提现参数account_type为CNPJ时 对应的 document_id 错误，24 ts长度错误，25 没提0.1就提现其它的
                             */
                            failType = payoutResultData?.error
                            if (failType != null && failType > 0) {
                                failType += 20
                                handleWithdrawFailed(failType, withdrawRecord)
                            }
                        }
                    }
                }
            }
        }
    }



    /**
     * 统一的失败处理
     */
    private fun handleWithdrawFailed(failReasonType: Int, withdrawRecord: RecordCash) {
        mBgScope.launch {
            // 1. 更新保存 提现记录状态
            withdrawRecord.withdrawState = TRANSACTION_STATE_FAIL
            withdrawRecord.withdrawFailType = failReasonType
            withdrawRecord.hasShowResultDialog = false

            RecordsManager.instance().updateCashRecord(withdrawRecord)

            // 2. 事件通知以便更新UI
            notifyWithdrawResult(withdrawRecord)

            // 3. Statistics
            StatisticUtil.reportEvents(StatisticUtil.KEY_Withdrawal_Reason, mapOf(
                "Reason_Type" to "Fail",
                "Fail_Reason" to failReasonType.toString() + " : " + getFailHintStrRes(failReasonType),
                "Withdrawal_Position" to withdrawRecord.amountNum,
                "Withdrawal_Day" to 1,
            ))

        }
    }


    private fun handleLoopCheckWithdrawSuccess(withdrawRecord: RecordCash) {
        // 1. 更新record 并保存
        withdrawRecord.withdrawState = TRANSACTION_STATE_SUCCESS
        RecordsManager.instance().updateCashRecord(withdrawRecord)

        // 2. 更新取现 条目状态
        if (withdrawRecord.withdrawItemIndex >= 0) {
            checkIfItemFinishAndReset(withdrawRecord.withdrawItemIndex)
        }

        // 3. event 通知
        notifyWithdrawResult(withdrawRecord)

        // 4. Statistic
        StatisticUtil.reportEvents(StatisticUtil.KEY_Withdrawal_Reason,
            mapOf("Reason_Type" to "Success",
                "Fail_Reason" to  0,
                "Withdrawal_Position" to withdrawRecord.amountNum,
                "Withdrawal_Day" to 1))

        // 5. 记录小额提现 已提现
        TaskManager.instance().newbieFirstWithdrawStatus().setSmallCashHasWithdrawed()
    }


}


data class WithdrawItem(
    val index: Int,
    val totalCashNum: Double,
    var totalProgress: Int = 0,
    val subItemList: List<WithdrawSubItem> = emptyList(),
    var startMs: Long = 0L,
    var hasStarted: Boolean = false,
    var isBigWithDraw: Boolean = true,
    var loopIndex: Int = 1
)

data class WithdrawSubItem(
    val dayIndex: Int,
    val cashTotal: Double,
    val startAdProgress: Int = 0,
    var currentAdProgress: Int = 0,
    var hasEarnMoneyByAd: Double = 0.0,
    var withdrawState: Int = STATE_NEED_WATCH_AD,
)