package com.gamedog.vididin.features.withdraw

import android.app.Activity
import android.content.Intent
import android.view.LayoutInflater
import androidx.activity.viewModels
import androidx.core.view.isVisible
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import androidx.recyclerview.widget.LinearLayoutManager
import com.ama.core.architecture.appBase.AppViewsEmptyViewModelActivity
import com.ama.core.architecture.util.AndroidUtil
import com.ama.core.architecture.util.CommonItemDecoration
import com.ama.core.architecture.util.DateUtil
import com.ama.core.architecture.util.setOnClickBatch
import com.gamedog.statisticreporter.StatisticUtil
import com.gamedog.vididin.VidiConst
import com.gamedog.vididin.VididinEvents
import com.gamedog.vididin.beans.WatchAdNotifyBean
import com.gamedog.vididin.beans.resp.PayoutReply
import com.gamedog.vididin.beans.resp.WithdrawRecord
import com.gamedog.vididin.core.login.login.AccountManager
import com.gamedog.vididin.features.withdraw.dialogs.WithdrawBindBankDialog
import com.gamedog.vididin.features.withdraw.dialogs.WithdrawFailDialog
import com.gamedog.vididin.features.withdraw.dialogs.WithdrawInfoConfirmDialog
import com.gamedog.vididin.features.withdraw.dialogs.WithdrawSuccessDialog
import com.gamedog.vididin.manager.WithdrawItemBean
import com.gamedog.vididin.manager.WithdrawManager
import com.gamedog.vididin.manager.WithdrawManager.Companion.INIT_OK
import com.gamedog.vididin.manager.WithdrawManager.Companion.TRANSACTION_STATE_FAIL
import com.gamedog.vididin.manager.WithdrawManager.Companion.TRANSACTION_STATE_ONGOING
import com.gamedog.vididin.manager.WithdrawManager.Companion.TRANSACTION_STATE_SUCCESS
import com.gamedog.vididin.router.Router
import com.viddin.videos.free.R
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.launch
import kotlin.getValue
import com.viddin.videos.free.databinding.ActivityWithdrawSubBinding as ViewBinding



@AndroidEntryPoint
class WithDrawSubActivity : AppViewsEmptyViewModelActivity<ViewBinding>() {
    private val viewModel: WithdrawViewModel by viewModels()

    private lateinit var mCurItem: WithdrawItemBean
    private var mSelectingIndex: Int = 0
    private var mType: Int = 0
    private val mAdapter: WithdrawSubAdapter by lazy { WithdrawSubAdapter( { itemIndex ->
        handleSubItemClicked(itemIndex)
    }) }


    override fun inflateViewBinding(inflater: LayoutInflater) = ViewBinding.inflate(inflater)

    override fun ViewBinding.initWindowInsets() {
        setImmerseRootView(contentRoot)
    }

    override fun ViewBinding.initViews() {
        mType = intent.getIntExtra(EXTRA_TYPE, 0)

        recyclerView.layoutManager = LinearLayoutManager(this@WithDrawSubActivity, LinearLayoutManager.HORIZONTAL, false)
        recyclerView.adapter = mAdapter
        recyclerView.addItemDecoration(CommonItemDecoration.create(18, 0, false))


        setOnClickBatch(flAction) {
            when(this) {
                flAction -> {
                    when (mCurItem.subItemList[mSelectingIndex].withdrawState) {
                        WithdrawManager.STATE_NEED_WATCH_AD -> {
                            gotoWatchAd()
                            sendClickStatistic()
                        }

                        WithdrawManager.STATE_COULD_WITHDRAW -> {
                            tryRequestWithdraw()
                        }
                    }
                }
            }
        }
    }

    private fun tryRequestWithdraw() {
        val subBean = mCurItem.subItemList[mSelectingIndex]
        if (AccountManager.isBankAccountExist()) {
            WithdrawInfoConfirmDialog(this@WithDrawSubActivity, { cashNum -> requestInit(cashNum) }).setWithDrawCashNum(subBean.cashTotal).show()
        } else {
            WithdrawBindBankDialog(this@WithDrawSubActivity, { cashNum -> requestInit(cashNum) }).setWithDrawCashNum(subBean.cashTotal).show()
        }
    }


    private fun saveNewRecord(payoutReply: PayoutReply, payCashNum: Double, timeMs: Long) {
        val newRecord = WithdrawRecord().apply {
            id = payoutReply.id!!
            recordNo = payoutReply.record_no
            cashNum = payCashNum
            operateMs = timeMs
            state = TRANSACTION_STATE_ONGOING
            failReason = 0

            itemIndex = mCurItem.index
            itemSubIndex = mSelectingIndex
        }
        WithdrawManager.instance().saveNewRecord(newRecord)
    }

    private fun requestInit(withdrawNum: Double) {
        lifecycleScope.launch {
            repeatOnLifecycle(Lifecycle.State.STARTED) {
                viewModel.InitData.collect { result ->
                    when (result) {
                        is com.gamedog.vididin.netbase.Result.Loading -> {

                        }
                        is com.gamedog.vididin.netbase.Result.Success -> {
                            val reqInitBean = result.data.data

                            reqInitBean?.let {
                                var errorHintRes = 0

                                if (it.error == 0 && !it.uuid.isNullOrEmpty() && !it.items.isNullOrEmpty()) {
                                    val itemId = if (withdrawNum <= VidiConst.WITHDRAW_SMALL_NUM) 0 else 1
                                    val withDrawItem = it.items?.get(itemId)!!
                                    if (withDrawItem.status == INIT_OK) {
                                        requestPayout(it.uuid!!, withDrawItem.id, withdrawNum)
                                    } else {
                                        errorHintRes = R.string.withdraw_fail_reach_day_limit
                                    }

                                } else {
                                    // 0成功，1失败，2签名验证失败，3客户端版本过低，4 ts长度错误
                                    when (it.error) {
                                        3-> errorHintRes = R.string.withdraw_fail_version_toolow
                                    }
                                }

                                if (errorHintRes > 0) {
                                    showFailDialog(errorHintRes)
                                }
                            }

                        }
                        is com.gamedog.vididin.netbase.Result.Error -> {
                            showFailDialog(R.string.withdraw_fail_unkown_error)
                        }
                    }
                }
            }
        }

        viewModel.withdrawInit()
    }

    private fun requestPayout(initUUID: String, payItemId: Int, payCashNum: Double) {
        val currentTimeMs = System.currentTimeMillis()

        lifecycleScope.launch {
            repeatOnLifecycle(Lifecycle.State.STARTED) {
                viewModel.PayoutResult.collect { result ->
                    when (result) {
                        is com.gamedog.vididin.netbase.Result.Loading -> {
                        }
                        is com.gamedog.vididin.netbase.Result.Success -> {
                            var errHintRes = 0

                            when (result.data?.data?.error) {
                                /* 错误码，
                                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就提现其它的
                                 */
                                0 -> {
                                    saveNewRecord(result.data.data!!, payCashNum, currentTimeMs)
                                }
                                5-> {
                                    errHintRes = R.string.withdraw_fail_region_restricit
                                }
                                8-> {
                                    errHintRes = R.string.withdraw_fail_amount_limit
                                }
                                9-> {
                                    errHintRes = R.string.withdraw_fail_amount_limit
                                }
                            }

                            if (errHintRes > 0) {
                                showFailDialog(errHintRes)
                            }
                        }
                        is com.gamedog.vididin.netbase.Result.Error -> {
                            showFailDialog(R.string.withdraw_fail_unkown_error)
                        }
                    }
                }
            }
        }


        viewModel.withdrawPayout(initUUID, payItemId, payCashNum)
    }


    private fun showSuccessDialog(cashNum: Double) {
        WithdrawSuccessDialog(this, cashNum).show()
    }

    private fun showFailDialog(errorHintRes: Int) {
        WithdrawFailDialog(this, errorHintRes).show()
    }

    private fun handleSubItemClicked(itemIndex: Int) {
        val mMaxDayIndex = DateUtil.getDaysPassed(mCurItem.startMs)
        if (itemIndex >= 0 && itemIndex <= mMaxDayIndex) {
            mSelectingIndex = itemIndex
            updateUI()
        }
    }

    private fun gotoWatchAd() {
        Router.WatchAd.startActivity(this, VidiConst.WATCH_AD_FOR_WITHDRAW_BIG, AndroidUtil.object2Json(mCurItem))
    }

    override fun ViewBinding.initListeners() {
        registerEvents({ data->
            when (data?.mEventType) {
                VididinEvents.EVENT_AD_WATCHED_FOR_WITHDRAW_BIG -> {
                    handleAdWatched(data.mData as WatchAdNotifyBean<WithdrawItemBean>)
                }

                VididinEvents.EVENT_WITHDRAW_SUB_ITEM_PROGRESS_UPDATED -> {
                    if ((data.mData as Int) == mSelectingIndex) {
                        updateProgressUI()
                    }
                }

                VididinEvents.EVENT_WITHDRAW_SELECTED_SUB_ITEM_CHANGED -> {
                    updateUI()
                }

                VididinEvents.EVENT_WITHDRAW_CHECK_RESULT_UPDATED -> {
                    try {
                        val record = data.mData as WithdrawRecord
                       if (record.itemIndex > 0) {
                           showTransactionResultDialog(record)
                       }
                    } catch (e: Exception) {
                        e.printStackTrace()
                    }
                }
            }
        }, VididinEvents.EVENT_AD_WATCHED_FOR_WITHDRAW_BIG,
            VididinEvents.EVENT_WITHDRAW_SUB_ITEM_PROGRESS_UPDATED,
            VididinEvents.EVENT_WITHDRAW_SELECTED_SUB_ITEM_CHANGED,
            VididinEvents.EVENT_WITHDRAW_CHECK_RESULT_UPDATED )


        mCurItem = WithdrawManager.instance().getItem(mType)
        if (mCurItem.startMs <= 0L) {
            WithdrawManager.instance().startItem(mCurItem)
        }
        mSelectingIndex = DateUtil.getDaysPassed(mCurItem.startMs)
        updateUI()
    }

    private fun showTransactionResultDialog(record: WithdrawRecord) {
        if (!record.hasShowResultDialog && record.state != TRANSACTION_STATE_ONGOING) {
            when (record.state) {
                TRANSACTION_STATE_SUCCESS -> {
                    showSuccessDialog(record.cashNum)
                    WithdrawManager.instance().saveRecordHasNotifyState(record.recordNo)
                }

                TRANSACTION_STATE_FAIL -> {
                    showFailDialog(WithdrawManager.instance().getFailHintStrRes(record.failReason))
                    WithdrawManager.instance().saveRecordHasNotifyState(record.recordNo)
                }
            }
        }
    }

    private fun handleAdWatched(adNotifyBean: WatchAdNotifyBean<WithdrawItemBean>) {
        val withdrawItemBean = adNotifyBean.extraData
        if (WithdrawManager.instance().addAdEarnForSubBean(withdrawItemBean.index,
                mSelectingIndex, adNotifyBean.earnMoneyNum * VidiConst.WITHDRAW_REWARD_AD_REVENUE_PERCENT)) {
            updateUI()
        }
    }

    private fun updateUI() {
        with(binding) {
            mAdapter.mSelectedSubIndex = mSelectingIndex
            mAdapter.submitList(mCurItem.subItemList)
            mAdapter.notifyDataSetChanged()
            recyclerView.scrollToPosition(mSelectingIndex)

            tvCashTotal.text = mCurItem.totalCashNum.toString()
            progressBar.enableTouch(false)
            progressBar.setBarColor(forColor = R.color.green_ce)
            updateProgressUI()
        }
    }

    private fun updateProgressUI() {
        with(binding) {
            val subBean = mCurItem.subItemList[mSelectingIndex]
            val curProgress = subBean.currentAdProgress
            progressBar.setProgress(curProgress)
            tvProgress.text = "$curProgress%"

            ivAction.isVisible = curProgress < 100
            if (curProgress < 100) {
                tvAction.setText(R.string.withdraw_cash_out)
                flAction.isClickable = true
                flAction.alpha = 1F

                sendShowStatistic()
            } else {
                var actionText = R.string.withdraw_cash_out
                when(subBean.withdrawState) {
                    WithdrawManager.STATE_COULD_WITHDRAW -> {
                        actionText = R.string.withdraw_cash_out
                        flAction.isClickable = true
                        flAction.alpha = 1F
                    }

                    WithdrawManager.STATE_WITHDRAWING -> {
                        actionText = R.string.pending
                        flAction.isClickable = false
                        flAction.alpha = 0.6F
                    }

                    WithdrawManager.STATE_HAS_WITHDRAWED -> {
                        actionText = R.string.withdraw_success
                        flAction.isClickable = false
                        flAction.alpha = 0.6F
                    }
                }
                tvAction.setText(actionText)
            }
        }
    }

    private fun sendShowStatistic() {
        StatisticUtil.reportEvents(StatisticUtil.KEY_RV_Button_Show, mapOf("Position" to "RV_Accelerate2"))
    }

    private fun sendClickStatistic() {
        StatisticUtil.reportEvents(StatisticUtil.KEY_RV_Button_Click_Game, mapOf("Position" to "RV_Accelerate2"))
    }

    override fun ViewBinding.initObservers() {

    }


    companion object {
        const val EXTRA_TYPE = "EXTRA_TYPE"
        internal fun startActivity(activity: Activity, withdrawType: Int) {
            activity.startActivity(Intent(activity.applicationContext,
                WithDrawSubActivity::class.java).apply { putExtra(EXTRA_TYPE, withdrawType) })
        }
    }
}

