package com.nivesh.production.partnerOnBoarding.ui.fragments

import android.annotation.SuppressLint
import android.app.Activity
import android.os.Bundle
import android.os.CountDownTimer
import android.text.Editable
import android.text.InputFilter
import android.text.TextWatcher
import android.util.Log
import android.view.KeyEvent
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.EditText
import android.widget.TextView
import androidx.fragment.app.Fragment
import com.google.gson.Gson
import com.nivesh.production.partnerOnBoarding.R
import com.nivesh.production.partnerOnBoarding.databinding.FragmentOtpBinding
import com.nivesh.production.partnerOnBoarding.model.request.SendOTPRequest
import com.nivesh.production.partnerOnBoarding.model.response.ValidateOTPResponse
import com.nivesh.production.partnerOnBoarding.ui.activities.BaseActivity
import com.nivesh.production.partnerOnBoarding.ui.activities.SignUpActivity
import com.nivesh.production.partnerOnBoarding.util.Common
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.RequestBody
import okhttp3.RequestBody.Companion.toRequestBody
import org.json.JSONObject
import java.util.concurrent.TimeUnit

class OTPFragment : BaseFragment() {
    private var _binding: FragmentOtpBinding? = null
    private val binding get() = _binding!!
    private var type: Int? = null
    private var mobile: String? = null
    var countDownTimer: CountDownTimer? = null
    var otpExpiryTime: Int = 0
    var timerTime: Long = 0
    var timeInSeconds = 0

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

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        type = arguments?.getInt("type")
        mobile = arguments?.getString("mobile")
        init()
    }

    private fun init() {

        smsAPI()

        binding.edtOTP1.filters = arrayOf<InputFilter>(InputFilter.LengthFilter(1))
        binding.edtOTP2.filters = arrayOf<InputFilter>(InputFilter.LengthFilter(1))
        binding.edtOTP3.filters = arrayOf<InputFilter>(InputFilter.LengthFilter(1))
        binding.edtOTP4.filters = arrayOf<InputFilter>(InputFilter.LengthFilter(1))
        binding.edtOTP5.filters = arrayOf<InputFilter>(InputFilter.LengthFilter(1))
        binding.edtOTP6.filters = arrayOf<InputFilter>(InputFilter.LengthFilter(1))

        binding.edtOTP1.addTextChangedListener(GenericTextWatcher(binding.edtOTP1, binding.edtOTP2))
        binding.edtOTP2.addTextChangedListener(GenericTextWatcher(binding.edtOTP2, binding.edtOTP3))
        binding.edtOTP3.addTextChangedListener(GenericTextWatcher(binding.edtOTP3, binding.edtOTP4))
        binding.edtOTP4.addTextChangedListener(GenericTextWatcher(binding.edtOTP4, binding.edtOTP5))
        binding.edtOTP5.addTextChangedListener(GenericTextWatcher(binding.edtOTP5, binding.edtOTP6))
        binding.edtOTP6.addTextChangedListener(GenericTextWatcher(binding.edtOTP6, null))

        binding.edtOTP1.setOnKeyListener(GenericKeyEvent(binding.edtOTP1, null))
        binding.edtOTP2.setOnKeyListener(GenericKeyEvent(binding.edtOTP2, binding.edtOTP1))
        binding.edtOTP3.setOnKeyListener(GenericKeyEvent(binding.edtOTP3, binding.edtOTP2))
        binding.edtOTP4.setOnKeyListener(GenericKeyEvent(binding.edtOTP4, binding.edtOTP3))
        binding.edtOTP5.setOnKeyListener(GenericKeyEvent(binding.edtOTP5, binding.edtOTP4))
        binding.edtOTP6.setOnKeyListener(GenericKeyEvent(binding.edtOTP6, binding.edtOTP5))

        binding.txtDigit.text = getString(R.string.sixDigitOTP).plus(" ").plus("\n+91 ".plus(mobile))

        binding.txtResendOTP.setOnClickListener {
            smsAPI()
        }

        binding.txtChangeNumber.setOnClickListener{
            (activity as SignUpActivity).onBackPressedDispatcher.onBackPressed()
        }

        binding.btnSubmit.setOnClickListener {
            if (validate()) {
                apiVerifyOTP()
            }
        }

        (activity as SignUpActivity).viewModelOne.getSendOTPMutableData.observe(
            viewLifecycleOwner
        ) { response ->
            val validateOTPResponse: ValidateOTPResponse =
                Gson().fromJson(
                    response?.data.toString(),
                    ValidateOTPResponse::class.java
                )
            if(validateOTPResponse.Status == getString(R.string.successText)){
                otpExpiryTime = validateOTPResponse.Result.ExpiryTimeInMinute
                binding.txtTimer.visibility = View.VISIBLE

                binding.txtTimer.text = otpExpiryTime.toString().plus(": 00")
                binding.txtTimerText.text = getString(R.string.secondsTimer).plus(" ").plus(otpExpiryTime).plus(" minute")
                showTimer((60000 * otpExpiryTime).toLong())
            }
        }
    }

    private fun showTimer(timerTime1: Long) {
        countDownTimer?.cancel()
        timerTime = 0
        timerMethod(timerTime1, binding.txtTimer, activity)
    }

    private fun timerMethod(timerMilliSec: Long, txt_timer: TextView, mActivity: Activity?) {
        try {
            countDownTimer = object : CountDownTimer(timerMilliSec, 1000) {
                @SuppressLint("SetTextI18n")
                override fun onTick(millisUntilFinished: Long) {
                    txt_timer.text = "(" + String.format(
                        "%02d:%02d",
                        TimeUnit.MILLISECONDS.toMinutes(millisUntilFinished),
                        TimeUnit.MILLISECONDS.toSeconds(millisUntilFinished) - TimeUnit.MINUTES.toSeconds(
                            TimeUnit.MILLISECONDS.toMinutes(millisUntilFinished)
                        )
                    ) + ")"
                    timerTime = millisUntilFinished
                    timeInSeconds = TimeUnit.MILLISECONDS.toSeconds(millisUntilFinished).toInt()
                }

                override fun onFinish() {
                    txt_timer.text = "00:00"
                    timerTime = 0
                    if (mActivity != null && !mActivity.isFinishing) {
                        resendOTPItemVisibility(View.VISIBLE)
                    }
                }
            }.start()
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    private fun apiVerifyOTP() {
        val obj = JSONObject()
        obj.put("OTP", "1234")
        obj.put("Mobile", mobile)
        obj.put("Email", "test@test.com")
        obj.put("ExpiryTimeInMinute", otpExpiryTime)

        val mediaType = "application/json; charset=utf-8".toMediaType()
        val body: RequestBody = obj.toString().toRequestBody(mediaType)

        (activity as SignUpActivity).viewModelOne.getVerifyOTP(
            body,
            (activity as SignUpActivity)
        )

        (activity as SignUpActivity).viewModelOne.getVerifyOTPMutableData.observe(
            viewLifecycleOwner
        ) { response ->
            Log.e("check_otp_res", response?.data.toString())
            countDownTimer?.cancel()
            val bundle = Bundle()
            bundle.putString("mobile", mobile)
            bundle.putString("arnType", arguments?.getString("arnType"))
            var fragment = Fragment()
            if (type == 4) {
                fragment = GetStartedFragment()
            } else if (type == 3) {
                fragment = NewDistributorSignStepOne()
            }

            fragment.arguments = bundle

            addFragment(
                activity as BaseActivity,
                R.id.signUpContainer,
                fragment,
                "GET STARTED",
                true
            )
        }
    }

    private fun smsAPI() {
        resendOTPItemVisibility(View.GONE)

        val sendOTPRequest = SendOTPRequest()
        sendOTPRequest.AMCID = ""
        sendOTPRequest.CommunicationValue = arguments?.getString("mobile").toString()
        sendOTPRequest.Mode = "sms"
        sendOTPRequest.MsgState = "PartnerRegistrationOTP"
        sendOTPRequest.Name = "Manoj Sigh"
        sendOTPRequest.ProductId = 0
        sendOTPRequest.UserRole = 3
        sendOTPRequest.UserId = "4988"

        (activity as SignUpActivity).viewModelOne.getSendOTP(
            sendOTPRequest,
            "",
            (activity as SignUpActivity)
        )
    }

    private fun resendOTPItemVisibility(viewType: Int) {
        binding.txtResendOTP.visibility = viewType
        binding.txtDidNotGetOTP.visibility = viewType
    }

    private fun validate(): Boolean {
        return if (binding.edtOTP1.text.toString().isEmpty()) { // EditText
            Common.commonErrorMethod(
                binding.edtOTP1,
                binding.tlOTP1,
                ""
            )
        } else if (binding.edtOTP2.text.toString().isEmpty()) { // EditText
            Common.commonErrorMethod(
                binding.edtOTP2,
                binding.tlOTP2,
                ""
            )
        } else if (binding.edtOTP3.text.toString().isEmpty()) { // EditText
            Common.commonErrorMethod(
                binding.edtOTP3,
                binding.tlOTP3,
                ""
            )
        } else if (binding.edtOTP4.text.toString().isEmpty()) { // EditText
            Common.commonErrorMethod(
                binding.edtOTP4,
                binding.tlOTP4,
                ""
            )
        } else if (binding.edtOTP5.text.toString().isEmpty()) { // EditText
            Common.commonErrorMethod(
                binding.edtOTP5,
                binding.tlOTP5,
                ""
            )
        } else if (binding.edtOTP6.text.toString().isEmpty()) { // EditText
            Common.commonErrorMethod(
                binding.edtOTP6,
                binding.tlOTP6,
                ""
            )
        } else {
            return true
        }
    }

    class GenericKeyEvent internal constructor(
        private val currentView: EditText,
        private val previousView: EditText?
    ) : View.OnKeyListener {
        override fun onKey(p0: View?, keyCode: Int, event: KeyEvent?): Boolean {
            if (event!!.action == KeyEvent.ACTION_DOWN && keyCode == KeyEvent.KEYCODE_DEL && currentView.id != R.id.edtOTP1 && currentView.text.isEmpty()) {
                previousView!!.text = null
                previousView.requestFocus()
                return true
            }
            return false
        }
    }

    class GenericTextWatcher internal constructor(
        private val currentView: View,
        private val nextView: View?
    ) : TextWatcher {
        override fun afterTextChanged(editable: Editable) {
            val text = editable.toString()
            when (currentView.id) {
                R.id.edtOTP1 -> if (text.length == 1) nextView!!.requestFocus()
                R.id.edtOTP2 -> if (text.length == 1) nextView!!.requestFocus()
                R.id.edtOTP3 -> if (text.length == 1) nextView!!.requestFocus()
                R.id.edtOTP4 -> if (text.length == 1) nextView!!.requestFocus()
                R.id.edtOTP5 -> if (text.length == 1) nextView!!.requestFocus()
            }
        }

        override fun beforeTextChanged(
            arg0: CharSequence,
            arg1: Int,
            arg2: Int,
            arg3: Int
        ) {
        }

        override fun onTextChanged(
            arg0: CharSequence,
            arg1: Int,
            arg2: Int,
            arg3: Int
        ) {
        }
    }
}