package com.seatel.mobilehall.ui.login.fragment

import android.content.Context
import android.os.Bundle
import android.os.CountDownTimer
import android.os.Handler
import android.text.TextUtils
import android.view.MotionEvent
import android.view.View
import android.widget.EditText
import android.widget.TextView
import com.android.volley.Request
import com.android.volley.VolleyError
import com.google.gson.Gson
import com.seatel.mobilehall.R
import com.seatel.mobilehall.data.network.SeatelJSONObjectRequest
import com.seatel.mobilehall.data.network.SeatelSuperRequest.getErrorMessageFrom
import com.seatel.mobilehall.data.prefs.SeatelSharePreferences
import com.seatel.mobilehall.ui.application.MyApplication
import com.seatel.mobilehall.ui.login.activity.LoginActivity
import com.seatel.mobilehall.ui.login.activity.UpdatedSimProfileActivity
import com.seatel.mobilehall.ui.login.interactor.ConfirmSignUpInteractor
import com.seatel.mobilehall.ui.login.interactor.SignUpInteractor
import com.seatel.mobilehall.ui.login.model.ProfileModel
import com.seatel.mobilehall.ui.login.model.ResetPasswordModel
import com.seatel.mobilehall.ui.login.presenter.ConfirmSignUpPresenter
import com.seatel.mobilehall.ui.login.presenter.SignUpPresenter
import com.seatel.mobilehall.util.AnimationUtil
import com.seatel.mobilehall.util.Constant
import com.seatel.mobilehall.util.SeatelAlertDialog
import com.seatel.mobilehall.util.SeatelUtils
import com.seatel.mobilehall.util.customview.CustomEditText
import com.seatel.mobilehall.util.customview.CustomKeyboard
import com.seatel.mobilehall.util.customview.ErrorHandleView
import com.seatel.mobilehall.util.interactor.KeyBoardNumberInteractor
import com.seatel.mobilehall.util.manager.OrderingManager
import kotlinx.android.synthetic.main.fragment_confirmation.*
import org.json.JSONObject
import java.util.*

open class ConfirmationFragment : MainFragment(), KeyBoardNumberInteractor,
    ConfirmSignUpInteractor.View, SignUpInteractor.View, View.OnTouchListener {

    private val OFFSET = 100
    private var mHiddenTextView: TextView? = null
    private val mEditTexts = ArrayList<CustomEditText>()
    private var mConfirmUserPresenter: ConfirmSignUpPresenter? = null
    private var mSignUpPresenter: SignUpPresenter? = null
    private lateinit var keyBoardNumberView: CustomKeyboard
    private var mPhone: String = ""
    private var mEmail: String = ""
    private var mPassword: String = ""
    private var mTypeRegister: String = ""
    private var mSocialType: String = ""
    private var mMainPhoneNumber = ""
    private lateinit var timerResend: CountDownTimer
    private var isCanceled = false
    var isRequesting = false
    private var handlerSMS: Handler? = null
    private var dialogAlert: SeatelAlertDialog? = null


    fun setDataPost(
        mPhone: String,
        mEmail: String,
        mPassword: String,
        mSocialType: String,
        mTypeRegister: String
    ) {
        this.mPhone = mPhone
        this.mEmail = mEmail
        this.mPassword = mPassword
        this.mTypeRegister = mTypeRegister
        this.mSocialType = mSocialType
    }

    fun setDataForAddPhoneNumber(phone: String) {
        this.mMainPhoneNumber = phone
    }

    fun isFeatureAddNewPhone(): Boolean {
        return mMainPhoneNumber.isNotEmpty()
    }

    fun getMainPhone(): String {
        return mMainPhoneNumber
    }

    fun getPhone(): String {
        return mPhone
    }

    fun getTypeConfirm(): String {
        return mTypeRegister
    }

    private fun showScreenNext(offnetNumber: Boolean) {

        if (TextUtils.equals(
                mTypeRegister,
                Constant.REGISTER
            ) or (TextUtils.equals(mTypeRegister, Constant.SOCIAL_REGISTER))
        ) {
            cancelRuningTimer()
            // Show Home screen
            SeatelSharePreferences.getInstance(getmContext())
                ?.setNoneSeatelNumber(offnetNumber) //SeatelUtils.checkIsNonSeatel(mPhone)
            SeatelSharePreferences.getInstance(getmContext())?.setPhoneLogin(mPhone)
            SeatelSharePreferences.getInstance(getmContext())?.setMainPhoneLogin(mPhone)
            SeatelUtils.gotoMainScreen(context)
            getMainActivity().closeHome()
            SeatelUtils.hideKeyboard(getmContext() as LoginActivity)
            SeatelSharePreferences.getInstance(requireContext())?.setLoginSuccess("true")
            keyboard_view.hideKeyBoard()

        }
    }

    override fun onDestroy() {
        super.onDestroy()
        mConfirmUserPresenter?.onDestroy()
        mSignUpPresenter?.onDestroy()
    }

    override fun onConfirmSucceed() {
        error_view.visibility = View.GONE
        cancelRuningTimer()
        when {
            getTypeConfirm().equals(Constant.VERRIFY_PHONE_NUMBER, true) -> {
                UpdatedSimProfileActivity.launch(getmContext(), mPhone)
                dialogAlert?.dimissDialog()
                getMainActivity().finish()
                return
            }
            isFeatureAddNewPhone() -> {
                MyApplication.isAddnewNumberDone = true
                SeatelSharePreferences.getInstance(getmContext())?.setPhoneLogin(mPhone)
                getMainActivity().closeHome()
                SeatelUtils.hideKeyboard(getmContext() as LoginActivity)
                keyboard_view.hideKeyBoard()
                return
            }
            else -> getProfileData()
        }
        isRequesting = false
        button_confirm.isEnabled = true

    }

    private fun getProfileData() {
        object : SeatelJSONObjectRequest(getmContext()) {

            override fun getFunctionName(): String {
                return "v2/seatel/profile?phoneNumber=${getPhone()}"
            }

            override fun getMethod(): Int {
                return Request.Method.GET
            }

        }.setOnErrorListener { _ ->
            SeatelAlertDialog.with(getmContext(), getString(R.string.register_success))
                .setPositiveButton(getString(R.string.yes)) { _, _ ->
                    showScreenNext(SeatelUtils.checkIsNonSeatel(mPhone))
                }.show()
        }.execute {
            it as JSONObject
            val profileModel = ProfileModel()
            profileModel.certType = it.optString("certType")
            profileModel.certNumber = it.optString("certNumber")
            profileModel.custName = it.optString("custName")
            profileModel.msisdn = it.optString("mSISDN")
            profileModel.email = it.optString("email")
            profileModel.imageUrl = it.optString("profilePicture")
            profileModel.isOffnetNumber =
                SeatelUtils.checkIsNoneSeatelType(it.optString("type", ""))
            profileModel.isSnowfall = it.optBoolean("snowfall", false)
            if (it.has("orderIds")) {
                val dataId = it.optJSONArray("orderIds")
                val idList: ArrayList<Int> = ArrayList()
                for (i in 0..(dataId.length() - 1)) {
                    idList.add(dataId.optInt(i))
                }
                profileModel.orderIdUnSuccess = idList
            }
            if (it.has("shipmentInsuranceRate"))
                OrderingManager.getInstance().shipmentInsuranceRate =
                    it.optDouble("shipmentInsuranceRate", 0.0)
            SeatelSharePreferences.getInstance(getmContext())
                ?.setUserInfo(Gson().toJson(profileModel))
            SeatelAlertDialog.with(getmContext(), getString(R.string.register_success))
                .setPositiveButton(getString(R.string.yes)) { _, _ ->
                    showScreenNext(profileModel.isOffnetNumber)
                }.show()
        }
    }

    override fun onConfirmFailed(error: VolleyError) {
        if (error_view != null) {
            isRequesting = false
            error_view.visibility = View.GONE
            dialogAlert?.dimissDialog()
            dialogAlert =
                SeatelAlertDialog.with(getMainActivity(), getErrorMessageFrom(error)).show()
            resetCodeInput()
            button_confirm.isEnabled = true

//            if (getHomeActivity() != null) {
//                getHomeActivity().startSMSService()
//            }
        }
    }

    override fun onRequestCodeSucceed(resetPasswordModel: ResetPasswordModel) {
        if (error_view != null) {
            isRequesting = false
            error_view.visibility = View.GONE
            startResendCountDown()
            tv_resend_code_confirm.isEnabled = true
        }
    }

    override fun onRequestCodeFailed(error: VolleyError) {
        isRequesting = false
        error_view.visibility = View.GONE
        SeatelAlertDialog.with(requireContext(), getErrorMessageFrom(error)).show()
        tv_resend_code_confirm.isEnabled = true
    }

    override fun onAttach(context: Context) {
        super.onAttach(context)
        setmContext(context)
        setActivity(context as LoginActivity)
        setFragmentLayout(R.layout.fragment_confirmation)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        mConfirmUserPresenter = ConfirmSignUpPresenter(getmContext(), this)
        mSignUpPresenter = SignUpPresenter(getmContext(), this)
        init()
    }

    override fun getFragmentOffset(): Int {
        return OFFSET
    }

    override fun onKeyBoardKeyClick(key: String) {
        onInsert(key)
    }

    override fun onKeyBoardKeyClearClick() {
        onClear()
    }

    private fun startConfirmCode() {
        if (isRequesting) return
        val codeConfirm = text_view_hidden.text.toString().trim()
        if (TextUtils.isEmpty(codeConfirm) || codeConfirm.length < 6) {
            SeatelAlertDialog.with(requireContext(), getString(R.string.enter_confirmation)).show()
            return
        }
        button_confirm.isEnabled = false
        isRequesting = true
        error_view.setViewMode(ErrorHandleView.Mode.LOADING)
        dialogAlert?.dimissDialog()
        mConfirmUserPresenter?.onConfirmCode(
            "v2/",
            codeConfirm,
            mEmail,
            "",
            mPhone,
            mPassword,
            mSocialType,
            mTypeRegister
        )
//        cancelRuningTimer()
    }

    fun startResendCountDown() {
        tv_resend_code_confirm.visibility = View.GONE
        layout_action_code_sent.visibility = View.VISIBLE

        timerResend = object : CountDownTimer(120000, 1000) {
            override fun onTick(millisUntilFinished: Long) {
                if (isCanceled) {
                    timerResend.cancel()
                    return
                }
                if (tv_confirm_code_sent != null) {
                    tv_confirm_code_sent.text = String.format(
                        Locale.US, "%s",
                        SeatelUtils.milliSecondsToTimer(millisUntilFinished)
                    )
                }
            }

            override fun onFinish() {
                if (tv_resend_code_confirm != null) {
                    tv_resend_code_confirm.visibility = View.VISIBLE
                    layout_action_code_sent.visibility = View.GONE
                }
            }
        }.start()
    }

    private fun onEditTextSearchTouch() {
        AnimationUtil.instance?.expand(layout_keyboard)
    }

    override fun onTouch(v: View?, event: MotionEvent?): Boolean {
        if (v != null)
            when (v.id) {
                R.id.edit_text_confirm_code_one, R.id.edit_text_confirm_code_two, R.id.edit_text_confirm_code_three, R.id.edit_text_confirm_code_four,
                R.id.edit_text_confirm_code_five, R.id.edit_text_confirm_code_six -> {
                    onEditTextSearchTouch()
                }
            }
        return false
    }

    private fun init() {

        startResendCountDown()
        button_confirm.setOnClickListener {
            AnimationUtil.instance?.collapse(layout_keyboard)
            startConfirmCode()
        }

//        getHomeActivity().setFilterSMS(SeatelUtils.checkIsNonSeatel(mPhone))
        tv_resend_code_confirm.setOnClickListener {
            error_view.setViewMode(ErrorHandleView.Mode.LOADING)
            resetCodeInput()
            onEditTextSearchTouch()
            startResendCountDown()
            isRequesting = true
            tv_resend_code_confirm.isEnabled = false
            mSignUpPresenter?.onRequestCode(mPhone, mEmail, mTypeRegister, "", "")
        }
        image_view_back.setOnClickListener { onBackPress() }
        keyBoardNumberView = keyboard_view
        keyBoardNumberView.setKeyBoardNumberInteractor(this)
        keyBoardNumberView.showKeyBoard()
        mEditTexts.add(edit_text_confirm_code_one)
        mEditTexts.add(edit_text_confirm_code_two)
        mEditTexts.add(edit_text_confirm_code_three)
        mEditTexts.add(edit_text_confirm_code_four)
        mEditTexts.add(edit_text_confirm_code_five)
        mEditTexts.add(edit_text_confirm_code_six)

        for (editText in mEditTexts) setEditTextTouchListener(editText)

        mEditTexts[0].requestFocus()
        mHiddenTextView = text_view_hidden
    }

    private fun setEditTextTouchListener(textEdit: EditText) {
        textEdit.setOnTouchListener(this)
        textEdit.showSoftInputOnFocus = false
    }

    private fun onInsert(key: String) {

        if (mHiddenTextView!!.text.length == mEditTexts.size) return
        val pos = getInsertPos(key)
        val textView = mEditTexts[pos]

        textView.setText(key)
//        textView.transformationMethod = HideReturnsTransformationMethod.getInstance()
//        textView.postDelayed(object : Runnable {
//            override fun run() {
//                textView.transformationMethod = PasswordTransformationMethod.getInstance()
//                textView.removeCallbacks(this)
//            }
//        }, 200)

        textView.isCursorVisible = false
        if (pos == mEditTexts.size - 1) return
        mEditTexts[pos + 1].requestFocus()
    }

    fun resetCodeInput() {
        text_view_hidden.text = ""
        val length = mEditTexts.size - 1
        for (i in 0..length) {
            mEditTexts[i].setText("")
        }
        mEditTexts[0].requestFocus()
        mEditTexts[0].isCursorVisible = true
    }

    private fun onClear() {
        if (mHiddenTextView!!.text.isEmpty()) return
        val pos = getClearPos()
        mEditTexts[pos].requestFocus()
        mEditTexts[pos].isCursorVisible = true
        mEditTexts[pos].setText("")
    }

    fun cancelRuningTimer() {
        isCanceled = true
        timerResend.cancel()
    }

    override fun onBackPress() {
        super.onBackPress()
        cancelRuningTimer()
        getmMainFragmentPresenter()!!.addFragment(SignUpFragment(), true)
    }

    private fun getInsertPos(key: String): Int {
        mHiddenTextView!!.text = mHiddenTextView!!.text.toString() + key
        return mHiddenTextView!!.text.length - 1
    }

    private fun getClearPos(): Int {
        mHiddenTextView!!.text =
            mHiddenTextView!!.text.subSequence(0, mHiddenTextView!!.length() - 1)
        return mHiddenTextView!!.text.length
    }

    fun smsResponse(body: String, sender: String) {
        if (sender == Constant.SENDER_NUMBER || sender == Constant.SENDER_NUMBER_OFFNET) {
            val code = body.split(": ")[1].replace(".", "")
            code(code)
        }
    }

    fun smsReceiver(body: String) {
        code(body)
    }

    open fun code(code: String) {
        if (TextUtils.isEmpty(code)) {
            SeatelAlertDialog.with(requireContext(), getString(R.string.enter_confirmation)).show()
            return
        }
        mHiddenTextView!!.text = code
        val chars = code.toCharArray()
        for ((i, char) in chars.withIndex()) {
            mEditTexts[i].setText(char.toString())
            if (i == 0) mEditTexts[i].isCursorVisible = false
        }

        handlerSMS = Handler()
        handlerSMS?.postDelayed({
            if (button_confirm != null)
                button_confirm.callOnClick()
        }, 0)
    }

}