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.graphics.toColorInt
import androidx.core.view.isVisible
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import com.ama.core.architecture.appBase.AppViewsEmptyViewModelActivity
import com.ama.core.architecture.highlightpro.HighlightPro
import com.ama.core.architecture.highlightpro.parameter.Constraints
import com.ama.core.architecture.highlightpro.parameter.HighlightParameter
import com.ama.core.architecture.highlightpro.parameter.MarginOffset
import com.ama.core.architecture.highlightpro.shape.RectShape
import com.ama.core.architecture.util.ResUtil
import com.ama.core.architecture.util.ResUtil.dp
import com.ama.core.architecture.util.SpUtil
import com.ama.core.architecture.util.setOnClickBatch
import com.gamedog.vididin.StatisticUtil
import com.gamedog.vididin.VidiConst
import com.viddin.videos.free.R
import com.gamedog.vididin.VididinEvents
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.features.withdraw.widget.WithDrawItemView
import com.gamedog.vididin.manager.TaskManager
import com.gamedog.vididin.manager.WithdrawManager
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.netbase.Result
import com.gamedog.vididin.router.Router
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.launch
import kotlin.getValue
import com.viddin.videos.free.databinding.ActivityWithdrawBinding as ViewBinding



@AndroidEntryPoint
class WithDrawActivity : AppViewsEmptyViewModelActivity<ViewBinding>() {

    private val viewModel: WithdrawViewModel by viewModels()
    private val mItemViewList: MutableList<WithDrawItemView> = mutableListOf()


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

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

    override fun ViewBinding.initViews() {
        titlebar.setTitleText(R.string.sacar)

        mItemViewList.add(withdraw01)
        mItemViewList.add(withdraw10)
        mItemViewList.add(withdraw20)
        mItemViewList.add(withdraw50)
        mItemViewList.add(withdraw100)
        mItemViewList.add(withdraw300)

        withdraw01.setNumAndAction(0, 0.1,
            { itemIndex->
                handleGotoWithdraw(itemIndex)
            })

        withdraw10.setNumAndAction(1, 10.0,
            { itemIndex->
                handleGotoWithdraw(itemIndex)
            })

        withdraw20.setNumAndAction(2, 20.0,
            { itemIndex->
                handleGotoWithdraw(itemIndex)
            })

        withdraw50.setNumAndAction(3, 50.0,
            { itemIndex->
                handleGotoWithdraw(itemIndex)
            })

        withdraw100.setNumAndAction(4, 100.0,
            { itemIndex->
                handleGotoWithdraw(itemIndex)
            })

        withdraw300.setNumAndAction(5, 300.0,
            { itemIndex->
                handleGotoWithdraw(itemIndex)
            })

        withdrawPix2.setIconAndText(R.mipmap.pix2_big, R.string.pix2, {
            WithdrawBindBankDialog(this@WithDrawActivity, null).setWithDrawCashNum(0.0).show()
        })

        withdrawPix2.setSelectedState(true)

        setOnClickBatch(withdrawRecord) {
            when(this) {
                withdrawRecord -> {
                    Router.WithdrawRecord.startActivity(this@WithDrawActivity)
                }
            }
        }

        updateUICashTotal()

        if (TaskManager.instance().newbieFirstWithdrawStatus().getStatusBean().hasClaimReward) {
            withdraw01.isVisible = false
        }
    }


    private fun handleGotoWithdraw(itemIndex: Int) {
        if (mItemViewList.get(itemIndex).getCashNum() > 1.0) {
            gotoWithdrawSubActivity(itemIndex)
        } else {
            val hasBindBank = AccountManager.hasValidBankInfo()
            val cashNum = mItemViewList.get(itemIndex).getCashNum()
            if (!hasBindBank) {
                WithdrawBindBankDialog(this@WithDrawActivity, { cashNum -> requestInit(cashNum) }).setWithDrawCashNum(cashNum).show()
            } else {
                WithdrawInfoConfirmDialog(this@WithDrawActivity, {
                    cashNum -> requestInit(cashNum)
                    WithdrawManager.instance().setItemStarted(0)
                }).setWithDrawCashNum(cashNum).show()
            }
        }
    }

    private fun updateUICashTotal() {
        binding.tvCashTotal.text = String.format("%.2f", AccountManager.getCash())
        binding.tvAllCashHasWithdrawed.text = buildString {
            append(ResUtil.getString(R.string.cash))
            append(" ")
            append(WithdrawManager.instance().getHasWithdrawSuccessCashCount())
        }
    }

    private fun udpateItemListUI() {
        mItemViewList.forEach {
            it.updateProgressAndButUI()
        }
    }


    override fun ViewBinding.initListeners() {
        registerEvents({ data->
            when (data?.mEventType) {
                VididinEvents.Event_Account_Cash_Changed -> {
                    updateUICashTotal()
                }

                VididinEvents.EVENT_AD_WATCHED_FOR_WITHDRAW_SMALL -> {
                    /*val notifyData: WatchAdNotifyBean<Float> = data.mData as WatchAdNotifyBean<Float>
                    requestInit(notifyData.extraData)*/
                }

                VididinEvents.EVENT_WITHDRAW_CHECK_RESULT_UPDATED -> {
                    try {
                        val record = data.mData as WithdrawRecord
                        if (record.itemIndex == 0) {
                            showTransactionResultDialog(record)
                        }
                        updateUICashTotal()
                        mItemViewList[record.itemIndex].updateProgressAndButUI()
                    } catch (e: Exception) {
                        e.printStackTrace()
                    }
                }

                VididinEvents.EVENT_WITHDRAW_ITEM_LIST_CHANGED -> {
                    udpateItemListUI()
                }

                VididinEvents.EVENT_BANK_INFO_CHANGED -> {
                    withdrawPix2.updateBankAccountInfo()
                }
            }

        }, VididinEvents.Event_Account_Cash_Changed,
            VididinEvents.EVENT_AD_WATCHED_FOR_WITHDRAW_SMALL,
            VididinEvents.EVENT_WITHDRAW_CHECK_RESULT_UPDATED,
            VididinEvents.EVENT_WITHDRAW_ITEM_LIST_CHANGED,
            VididinEvents.EVENT_BANK_INFO_CHANGED)

        readTransactionsAndShowResult()

        if (needShowGuide()) {
            binding.tvCashTotal.postDelayed({
                showGuide()
            }, 5)
        }
    }


    override fun ViewBinding.initObservers() {
        //TODO("Not yet implemented")
    }


    private fun requestInit(withdrawNum: Double) {
        lifecycleScope.launch {
            viewModel.InitData.collect { result ->
                when (result) {
                    is Result.Loading -> {

                    }
                    is 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_ACTIVE) {
                                    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 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 Result.Loading -> {
                        }
                        is 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 Result.Error -> {
                            showFailDialog(R.string.withdraw_fail_unkown_error)
                        }
                    }
                }
            }
        }


        viewModel.withdrawPayout(initUUID, payItemId, payCashNum)
    }

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

    private fun showFailDialog(failType: Int) {
        WithdrawFailDialog(this@WithDrawActivity, failType).show()
    }

    private fun gotoWithdrawSubActivity(selectedIndex: Int) {
        Router.WithdrawSub.startActivity(this, selectedIndex)
        WithdrawManager.instance().setItemStarted(selectedIndex)
    }



    // ------------------------ new added -------------------------//

    private fun readTransactionsAndShowResult() {
        val recordList = WithdrawManager.instance().getClonedRecordList()
        recordList.forEach {
            showTransactionResultDialog(it)
        }
    }

    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().getFailShowTextRes(record.failReason))
                    WithdrawManager.instance().saveRecordHasNotifyState(record.recordNo)
                }
            }
        }
    }

    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 = 1
            failReason = 0
        }

        WithdrawManager.instance().saveNewRecord(newRecord)
    }

    private fun needShowGuide(): Boolean {
        return SpUtil.instance().getInt(SpUtil.KEY_GUIDE_HAS_SHOW) < 5
    }

    private fun saveGuideState() {
        SpUtil.instance().putInt(SpUtil.KEY_GUIDE_HAS_SHOW, 4)
    }

    override fun onDestroy() {
        super.onDestroy()
    }

    private fun showGuide() {
        HighlightPro.with(this@WithDrawActivity)
            .setHighlightParameter {
                HighlightParameter.Builder()
                    .setHighlightView(mItemViewList.get(0), {
                    })
                    .setTipsViewId(R.layout.guide_step_withdraw)
                    .setHighlightShape(RectShape(10.dp, 10.dp, 10.dp))
                    .setHighlightHorizontalPadding(0.dp)
                    .setConstraints(Constraints.TopToBottomOfHighlight + Constraints.EndToEndOfHighlight)
                    .setMarginOffset(MarginOffset(top = -20.dp.toInt(), end = 20.dp.toInt()))
                    .build()
            }
            .setBackgroundColor("#cc000000".toColorInt())
            .setOnShowCallback { index ->

            }
            .setOnDismissCallback {
                saveGuideState()
                handleGotoWithdraw(0)
            }
            .interceptBackPressed(true)
            .show()

        StatisticUtil.reportEvents(StatisticUtil.KEY_Guide, mapOf("Guide" to 3))

    }


    companion object {
        const val INIT_ACTIVE = 1

        internal fun startActivity(activity: Activity) {
            activity.startActivity(Intent(activity.applicationContext, WithDrawActivity::class.java))
        }
    }

}