package kr.co.vividnext.sodalive.mypage.can.payment

import android.annotation.SuppressLint
import android.content.Intent
import android.os.Handler
import android.os.Looper
import android.widget.TextView
import android.widget.Toast
import androidx.core.content.ContextCompat
import androidx.core.content.IntentCompat
import androidx.core.content.res.ResourcesCompat
import com.google.gson.Gson
import com.orhanobut.logger.Logger
import kr.co.bootpay.android.Bootpay
import kr.co.bootpay.android.events.BootpayEventListener
import kr.co.bootpay.android.models.BootUser
import kr.co.bootpay.android.models.Payload
import kr.co.vividnext.sodalive.BuildConfig
import kr.co.vividnext.sodalive.R
import kr.co.vividnext.sodalive.base.BaseActivity
import kr.co.vividnext.sodalive.common.Constants
import kr.co.vividnext.sodalive.common.SharedPreferenceManager
import kr.co.vividnext.sodalive.databinding.ActivityCanPaymentBinding
import kr.co.vividnext.sodalive.extensions.fontSpan
import kr.co.vividnext.sodalive.extensions.moneyFormat
import kr.co.vividnext.sodalive.mypage.auth.BootpayResponse
import kr.co.vividnext.sodalive.mypage.can.charge.pg.CanResponse
import kr.co.vividnext.sodalive.mypage.can.charge.pg.VerifyRequest
import kr.co.vividnext.sodalive.mypage.can.status.CanStatusActivity
import org.koin.android.ext.android.inject

class CanPaymentActivity : BaseActivity<ActivityCanPaymentBinding>(
    ActivityCanPaymentBinding::inflate
) {
    enum class PaymentMethod(val method: String) {
        CARD("카드"),
        BANK("계좌이체"),
        PHONE("휴대폰"),
        KAKAOPAY("카카오페이")
    }

    private val viewModel: CanPaymentViewModel by inject()

    private var canResponse: CanResponse? = null
    private var gotoPrevPage: Boolean = false
    private var isKakao: Boolean = false

    private val handler = Handler(Looper.getMainLooper())

    @SuppressLint("SetTextI18n")
    override fun setupView() {
        canResponse = IntentCompat.getParcelableExtra(
            intent,
            Constants.EXTRA_CAN,
            CanResponse::class.java
        )

        if (canResponse == null) {
            Toast.makeText(
                applicationContext,
                "다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다.",
                Toast.LENGTH_LONG
            ).show()

            finish()
        }

        gotoPrevPage = intent.getBooleanExtra(
            Constants.EXTRA_GO_TO_PREV_PAGE,
            false
        )

        binding.toolbar.tvBack.text = "결제하기"
        binding.toolbar.tvBack.setOnClickListener { finish() }

        binding.tvChargeCanTitle.text = canResponse!!.title
        binding.tvPrice.text = canResponse!!.price.moneyFormat()
        binding.tvPaymentPrice.text = "${canResponse!!.price.moneyFormat()}원".fontSpan(
            ResourcesCompat.getFont(applicationContext, R.font.gmarket_sans_light),
            "원"
        )

        binding.tvAgree.setOnClickListener {
            binding.tvAgree.isSelected = !binding.tvAgree.isSelected
        }

        binding.tvPayment.setOnClickListener {
            if (viewModel.paymentMethodLiveData.value == null) {
                Toast.makeText(
                    applicationContext,
                    "결제수단을 선택해 주세요.",
                    Toast.LENGTH_LONG
                ).show()
                return@setOnClickListener
            }

            if (!binding.tvAgree.isSelected) {
                Toast.makeText(
                    applicationContext,
                    "결제 진행에 동의하셔야 결제가 가능합니다.",
                    Toast.LENGTH_LONG
                ).show()
                return@setOnClickListener
            }

            requestCharge()
        }

        binding.tvMethodCard.setOnClickListener { viewModel.setPaymentMethod(PaymentMethod.CARD) }
        binding.tvMethodBank.setOnClickListener { viewModel.setPaymentMethod(PaymentMethod.BANK) }
        binding.tvMethodPhone.setOnClickListener { viewModel.setPaymentMethod(PaymentMethod.PHONE) }
        binding.flMethodKakaopay.setOnClickListener {
            viewModel.setPaymentMethod(PaymentMethod.KAKAOPAY)
        }

        viewModel.paymentMethodLiveData.observe(this) {
            allPaymentMethodSelectFalse()

            if (it != null) {
                when (it) {
                    PaymentMethod.CARD -> paymentMethodSelect(binding.tvMethodCard)
                    PaymentMethod.BANK -> paymentMethodSelect(binding.tvMethodBank)
                    PaymentMethod.PHONE -> paymentMethodSelect(binding.tvMethodPhone)
                    PaymentMethod.KAKAOPAY -> {
                        isKakao = true
                        binding.flMethodKakaopay
                            .setBackgroundResource(R.drawable.bg_round_corner_10_13181b_3bb9f1)
                    }
                }
            }
        }
    }

    private fun allPaymentMethodSelectFalse() {
        isKakao = false
        paymentMethodSelectFalse(binding.tvMethodBank)
        paymentMethodSelectFalse(binding.tvMethodCard)
        paymentMethodSelectFalse(binding.tvMethodPhone)
        binding.flMethodKakaopay
            .setBackgroundResource(R.drawable.bg_round_corner_10_232323_777777)
    }

    private fun paymentMethodSelectFalse(view: TextView) {
        view.typeface = ResourcesCompat.getFont(
            applicationContext,
            R.font.gmarket_sans_medium
        )

        view.setTextColor(ContextCompat.getColor(applicationContext, R.color.color_eeeeee))
        view.setBackgroundResource(R.drawable.bg_round_corner_10_232323_777777)
    }

    private fun paymentMethodSelect(view: TextView) {
        view.typeface = ResourcesCompat.getFont(
            applicationContext,
            R.font.gmarket_sans_bold
        )

        view.setTextColor(ContextCompat.getColor(applicationContext, R.color.color_3bb9f1))
        view.setBackgroundResource(R.drawable.bg_round_corner_10_13181b_3bb9f1)
    }

    private fun requestCharge() {
        viewModel.chargeCan(
            canId = canResponse!!.id,
            paymentGateway = PaymentGateway.PG,
            onSuccess = {
                requestPayment(chargeId = it)
            },
            onFailure = {
                Toast.makeText(applicationContext, it, Toast.LENGTH_LONG).show()
            }
        )
    }

    private fun requestPayment(chargeId: Long) {
        var payload = Payload()
            .setApplicationId(BuildConfig.BOOTPAY_APP_HECTO_ID)
            .setOrderId("$chargeId")
            .setOrderName(canResponse!!.title)
            .setPrice(canResponse!!.price.toDouble())
            .setTaxFree(0.toDouble())
            .setPg(
                if (isKakao) {
                    "카카오"
                } else {
                    "세틀뱅크"
                }
            )
            .setMethod(viewModel.paymentMethodLiveData.value!!.method)

        var username = SharedPreferenceManager.nickname

        if (username.length > 10) {
            username = "${username.take(6)}..."
        }

        val user = BootUser()
            .setId("${SharedPreferenceManager.userId}")
            .setUsername(username)

        payload = payload.setUser(user)

        Bootpay.init(this, this)
            .setPayload(payload)
            .setEventListener(object : BootpayEventListener {
                override fun onCancel(data: String) {
                    Logger.e("onCancel: $data")
                }

                override fun onError(data: String) {
                    Logger.e("onError: $data")
                    Toast.makeText(applicationContext, data, Toast.LENGTH_LONG).show()
                }

                override fun onClose() {
                    Logger.e("onClose")
                    Bootpay.removePaymentWindow()
                }

                override fun onIssued(data: String) {
                    Logger.e("onIssued: $data")
                }

                override fun onConfirm(data: String): Boolean {
                    Logger.e("onConfirm: $data")
                    return true
                }

                override fun onDone(data: String) {
                    Logger.e("onDone: $data")
                    handler.post {
                        verifyPayment(data)
                        Bootpay.removePaymentWindow()
                    }
                }
            }).requestPayment()
    }

    private fun verifyPayment(data: String) {
        val bootpayResponse = Gson().fromJson(data, BootpayResponse::class.java)
        val request = VerifyRequest(bootpayResponse.data.receiptId, bootpayResponse.data.orderId)

        viewModel.verifyHecto(
            request,
            onSuccess = {
                Toast.makeText(applicationContext, "캔이 충전되었습니다", Toast.LENGTH_LONG).show()
                SharedPreferenceManager.can += (canResponse!!.rewardCan + canResponse!!.can)
                if (gotoPrevPage) {
                    setResult(RESULT_OK)
                } else {
                    val intent = Intent(applicationContext, CanStatusActivity::class.java)
                    startActivity(intent)
                }
                finish()
            },
            onFailure = {
                Toast.makeText(applicationContext, it, Toast.LENGTH_LONG).show()
            }
        )
    }
}
