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

import android.annotation.SuppressLint
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.view.View
import android.widget.TextView
import android.widget.Toast
import androidx.core.content.ContextCompat
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.LoadingDialog
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.VerifyRequest
import org.koin.android.ext.android.inject

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

    private val viewModel: CanPaymentTempViewModel by inject()

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

    private lateinit var loadingDialog: LoadingDialog
    private lateinit var title: String
    private var can: Int = 0

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        bindData()
    }

    @SuppressLint("SetTextI18n")
    override fun setupView() {
        title = intent.getStringExtra("title") ?: ""
        can = intent.getIntExtra("can", 0)
        loadingDialog = LoadingDialog(this, layoutInflater)

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

            finish()
        }

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

        binding.ivCan.visibility = View.GONE
        binding.tvAlert.visibility = View.GONE
        binding.tvChargeCanTitle.text = title
        binding.tvPrice.text = (can * 110).moneyFormat()
        binding.tvPaymentPrice.text = "${(can * 110).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) }
    }

    private fun allPaymentMethodSelectFalse() {
        paymentMethodSelectFalse(binding.tvMethodBank)
        paymentMethodSelectFalse(binding.tvMethodCard)
        paymentMethodSelectFalse(binding.tvMethodPhone)
    }

    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(
            can = can,
            paymentGateway = PaymentGateway.PG,
            onSuccess = {
                requestPayment(chargeId = it)
            },
            onFailure = {
                Toast.makeText(applicationContext, it, Toast.LENGTH_LONG).show()
            }
        )
    }

    private fun requestPayment(chargeId: Long) {
        val user = BootUser()
            .setId("${SharedPreferenceManager.userId}")
            .setUsername(SharedPreferenceManager.nickname)

        val payload = Payload()
            .setApplicationId(BuildConfig.BOOTPAY_APP_HECTO_ID)
            .setOrderId("$chargeId")
            .setOrderName(title)
            .setPrice((can * 110).toDouble())
            .setTaxFree(0.toDouble())
            .setPg("세틀뱅크")
            .setMethod(viewModel.paymentMethodLiveData.value!!.method)
            .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.verify(
            request,
            onSuccess = {
                SharedPreferenceManager.can += can
                setResult(RESULT_OK)
                finish()
            },
            onFailure = {
                Toast.makeText(applicationContext, it, Toast.LENGTH_LONG).show()
            }
        )
    }

    private fun bindData() {
        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)
                }
            }
        }

        viewModel.isLoading.observe(this) {
            if (it) {
                loadingDialog.show(screenWidth, "")
            } else {
                loadingDialog.dismiss()
            }
        }
    }
}
