package com.seatel.mobilehall.ui.home.fragment

import android.Manifest
import android.content.Context
import android.os.Build
import android.os.Bundle
import android.text.TextUtils
import android.view.LayoutInflater
import android.view.MotionEvent
import android.view.View
import android.view.ViewGroup
import android.view.ViewTreeObserver
import android.widget.EditText
import android.widget.RadioButton
import android.widget.Toast
import androidx.core.content.ContextCompat
import com.android.volley.VolleyError
import com.journeyapps.barcodescanner.ScanContract
import com.journeyapps.barcodescanner.ScanIntentResult
import com.journeyapps.barcodescanner.ScanOptions
import com.seatel.mobilehall.R
import com.seatel.mobilehall.data.network.SeatelSuperRequest
import com.seatel.mobilehall.databinding.FragmentPinBinding
import com.seatel.mobilehall.ui.base.fragment.BaseFragment
import com.seatel.mobilehall.ui.home.activity.ConfirmationActivity
import com.seatel.mobilehall.ui.invite_friend.InviteFriendScanQrActivity
import com.seatel.mobilehall.ui.login.interactor.VerifyPinInteractor
import com.seatel.mobilehall.ui.login.presenter.VerifyPinPresenter
import com.seatel.mobilehall.util.AnimationUtil
import com.seatel.mobilehall.util.Constant
import com.seatel.mobilehall.util.FirebaseAnalyticsUtil
import com.seatel.mobilehall.util.PermissionUtil
import com.seatel.mobilehall.util.SeatelAlertDialog
import com.seatel.mobilehall.util.SeatelUtils
import com.seatel.mobilehall.util.customview.ErrorHandleView
import com.seatel.mobilehall.util.viewFragmentBinding
import org.json.JSONObject

class PinFragment : BaseFragment(), VerifyPinInteractor.View {

    private var mRadioButton: RadioButton? = null
    private lateinit var mView: View
    private var mIsFocus: Boolean = true
    private var mPhone = ""
    private var mPhotoRequest: PermissionUtil.PermissionRequestObject? = null

    // Verify Pin
    private lateinit var mVerifyPinPresenter: VerifyPinPresenter
    private lateinit var mVerifyPinInteractor: VerifyPinInteractor.View

    private val binding by viewFragmentBinding(
        FragmentPinBinding::inflate
    )

    override fun onVerifyPinNumberSucceed(response: JSONObject) {
        binding.errorView.visibility = View.GONE
        val amount = response.optDouble("amount", 0.0)
        val pin = binding.editTextAmount.text.toString()
        ConfirmationActivity.lunch(
            getmContext(), binding.editTextTopUpPhoneNumber.text.toString(),
            amount, true, pin
        )
    }

    override fun onVerifyPinNumberFailed(error: VolleyError) {
        binding.errorView.visibility = View.GONE
        SeatelAlertDialog.with(getmContext(), SeatelSuperRequest.getErrorMessageFrom(error)).show()
    }

    fun getViewPhoneNumber(): View {
        return binding.viewPhoneNumber
    }

    fun getViewAmount(): View {
        return binding.viewAmount
    }

    fun setPhoneNuber(phone: String) {
        this.mPhone = phone
    }

    override fun onAttach(context: Context) {
        super.onAttach(context)
        setmContext(context)
        //   setFragmentLayout(R.layout.fragment_pin)
        FirebaseAnalyticsUtil.getInstance(context).logCustomEvent(Constant.TAB_TOP_UP_PIN)
    }

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        return binding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        mView = view
        init()
    }

    private fun showKeyboard() {
        if (!isKeyboardHided()) return
        mView.postDelayed(object : Runnable {
            override fun run() {
                if (mIsFocus) {
                    binding.editTextAmount.requestFocus()
                    binding.editTextAmount.isFocusable = true
                    binding.keyboardViewTopUp.showKeyBoard(binding.editTextAmount)
                } else {
                    binding.keyboardViewTopUp.showKeyBoard(binding.editTextTopUpPhoneNumber)
                }
                mView.removeCallbacks(this)
            }
        }, 200)
    }

    override fun setUserVisibleHint(isVisibleToUser: Boolean) {
        super.setUserVisibleHint(isVisibleToUser)

        if (isVisibleToUser) {
            mView.postDelayed(object : Runnable {
                override fun run() {
                    if (mIsFocus) {
                        binding.editTextAmount.requestFocus()
                    } else binding.editTextTopUpPhoneNumber.requestFocus()
                    mView.removeCallbacks(this)
                }
            }, 200)
        }
    }

    override fun onDestroyView() {
        super.onDestroyView()
        binding.keyboardViewTopUp.hideKeyBoard()
    }

    private fun init() {
        mVerifyPinInteractor = this
        mVerifyPinPresenter = VerifyPinPresenter(getmContext(), this)

        setRadioButtonTextStyle()
        setUpRadioButton()

        binding.editTextTopUpPhoneNumber.hint = binding.editTextTopUpPhoneNumber.hint
        binding.editTextTopUpPhoneNumber.setText(SeatelUtils.phoneNumberFormat(mPhone))
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            binding.editTextTopUpPhoneNumber.showSoftInputOnFocus = false
            binding.editTextAmount.showSoftInputOnFocus = false
        }

        binding.editTextAmount.setSelection(binding.editTextAmount.text!!.length)
        binding.editTextAmount.setSelection(0)
        binding.keyboardViewTopUp.setmMaxLenght(30)
        binding.keyboardViewTopUp.showKeyBoard(binding.editTextAmount)
        binding.editTextTopUpPhoneNumber.clearFocus()

        binding.editTextTopUpPhoneNumber.setOnTouchListener { v: View, m: MotionEvent ->
            if (m.action == MotionEvent.ACTION_DOWN) {
                binding.editTextAmount.clearFocus()
                binding.editTextTopUpPhoneNumber.requestFocus()
                binding.keyboardViewTopUp.setmMaxLenght(15)
                binding.keyboardViewTopUp.showKeyBoard(v as EditText)
                AnimationUtil.instance?.collapse(binding.viewRadioButton.radioGroupTopUp)
                binding.linearLayoutPinless.animate().translationY(0f).duration = 300
                mIsFocus = false
            }
            false
        }

        binding.editTextAmount.viewTreeObserver.addOnGlobalLayoutListener(
            object : ViewTreeObserver.OnGlobalLayoutListener {
                override fun onGlobalLayout() {
                    binding.editTextAmount.requestFocus()
                    binding.editTextAmount.viewTreeObserver.removeOnGlobalLayoutListener(this)
                }
            })

        binding.editTextAmount.setOnTouchListener { v: View, m: MotionEvent ->
            if (m.action == MotionEvent.ACTION_DOWN) {
                binding.keyboardViewTopUp.setmMaxLenght(30)
                binding.keyboardViewTopUp.showKeyBoard(v as EditText)
                binding.editTextAmount.requestFocus()
                binding.editTextTopUpPhoneNumber.clearFocus()
                mIsFocus = true
            }
            false
        }

        binding.editTextTopUpPhoneNumber.isFocusable = true
        binding.relativeParentPinless.setOnClickListener { hideKeyBoard() }

        binding.imageScanBarcode.setOnClickListener {
            val options = ScanOptions()
            options.setDesiredBarcodeFormats(ScanOptions.ALL_CODE_TYPES)
            options.setCameraId(0) // Use a specific camera of the device
            options.setBeepEnabled(false)
            options.setOrientationLocked(false)
            options.setBarcodeImageEnabled(true)
            barcodeLauncher.launch(options)
        }
    }

    // Register the launcher and result handler
    private val barcodeLauncher = registerForActivityResult(
        ScanContract()
    ) { result: ScanIntentResult ->
        if (result.contents != null) {
            val mResult = result.contents.substringBeforeLast("*")
            val finalResult = mResult.substringAfterLast("*")
            binding.editTextAmount.setText(finalResult)
        }
    }

    private fun validateControl(): Boolean {
        val amount = binding.editTextAmount.text.toString().trim()
        var phone = binding.editTextTopUpPhoneNumber.text?.trim().toString()
        phone = phone.replace(" ", "")

        var strMessage = ""

        if (TextUtils.isEmpty(phone)) {
            strMessage = getString(R.string.phone_empty)

        } else if (phone.startsWith("0") && phone.length < 9 ||
            phone.startsWith("85") && phone.length < 11 || phone.length < 8
        )
            strMessage = getString(R.string.incorrect_phone_num)
        else if (TextUtils.isEmpty(amount))
            strMessage = getString(R.string.topup_pin_empty)

        if (!TextUtils.isEmpty(strMessage)) {
            SeatelAlertDialog.with(getmContext(), strMessage).show()
            return false
        }

        return true
    }

    private fun startVerifyPin() {
        binding.errorView.setViewMode(ErrorHandleView.Mode.LOADING)
        val pin = binding.editTextAmount.text.toString()
        mVerifyPinPresenter.onVerifyPinNumber(pin)
    }

    private fun setUpRadioButton() {
        mRadioButton = binding.viewRadioButton.radioButton5Dollar
        binding.viewRadioButton.radioGroupTopUp.setOnCheckedChangeListener { radioGroup, _ ->
            if (mRadioButton != null) {
                mRadioButton!!.setTextColor(
                    ContextCompat.getColor(
                        getmContext(),
                        R.color.colorBlue
                    )
                )
                mRadioButton!!.textSize = 16f
            }

            val radioButtonId: Int = radioGroup.checkedRadioButtonId
            val radioButton = radioGroup.findViewById<RadioButton>(radioButtonId)
            radioButton.setTextColor(ContextCompat.getColor(getmContext(), android.R.color.white))
            radioButton.textSize = 18f
            binding.editTextAmount.setText(radioButton.tag.toString())

            mRadioButton = radioButton
            binding.editTextAmount.setSelection(binding.editTextAmount.text!!.length)
        }

        binding.buttonNext.setOnClickListener {
            hideKeyBoard()
            if (validateControl()) {
                startVerifyPin()
            }
        }
    }

    override fun isKeyboardHided(): Boolean {
        return binding.keyboardViewTopUp.visibility == View.GONE
    }

    override fun hideKeyBoard() {
        super.hideKeyBoard()
        binding.keyboardViewTopUp.hideKeyBoard()
    }

    private fun setRadioButtonTextStyle() {
        val topUp = resources.getStringArray(R.array.top_up_amount)
        for (i in 0 until binding.viewRadioButton.radioGroupTopUp.childCount) {
            (binding.viewRadioButton.radioGroupTopUp.getChildAt(i) as RadioButton).text =
                SeatelUtils.fromHtml(topUp[i])
        }
    }

    private fun showPermissionCamera() {
        mPhotoRequest = PermissionUtil.with(this).request(Manifest.permission.CAMERA)
            .onAllGranted(object : PermissionUtil.Func() {
                override fun call() {
                    InviteFriendScanQrActivity.launchForResult(requireContext())
                }
            }).onAnyDenied(object : PermissionUtil.Func() {
                override fun call() {
                    Toast.makeText(
                        requireContext(),
                        "Camera permission is needed to open camera.",
                        Toast.LENGTH_LONG
                    ).show()
                }
            }).askPermission(999)
    }
}
