package com.lemonhc.mplus.mcare_plus.activity.lockScreen

import android.app.Activity
import android.content.Context
import android.content.Intent
import android.graphics.Color
import android.graphics.Typeface
import android.graphics.drawable.ColorDrawable
import android.os.Bundle
import android.os.SystemClock
import android.os.Vibrator
import android.util.Log
import android.view.View
import android.view.ViewGroup
import android.view.Window
import android.view.WindowManager
import android.widget.Button
import android.widget.TextView

//import com.github.ajalt.reprint.core.AuthenticationFailureReason
//import com.github.ajalt.reprint.core.AuthenticationListener
//import com.github.ajalt.reprint.core.Reprint

import com.lemonhc.mplus.framework.constant.FrameworkConstant
import com.lemonhc.mplus.framework.util.PreferenceUtil
import com.lemonhc.mplus.framework.util.encription.AES
import com.lemonhc.mplus.framework.util.kotlinExtension.isCaptureFlag
import com.lemonhc.mplus.mcare_plus.R

import org.jetbrains.anko.AnkoLogger
import org.jetbrains.anko.debug

import java.util.ArrayList

class LockScreenActivity: Activity() {
    var arrPreviousPassword: ArrayList<Any>? = null
    var arrPassword: ArrayList<Any>? = null
    var title: TextView? = null
    var description: TextView? = null
    var mType: FrameworkConstant.passwordInputType = FrameworkConstant.passwordInputType.FIRST_INPUT
    var context: Context = this

    internal var fingerPrintCount = 0
//    private var authFingerprint: AuthFingerprint? = null
    private var type: FrameworkConstant.passwordInputType? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        this.requestWindowFeature(Window.FEATURE_NO_TITLE)
        super.onCreate(savedInstanceState)
        if (!isCaptureFlag) {
            window.addFlags(WindowManager.LayoutParams.FLAG_SECURE)
        }

        setContentView(R.layout.activity_lock_screen).run {
            title = findViewById(R.id.password_title)
            description = findViewById(R.id.password_description)
        }

        val util: PreferenceUtil = PreferenceUtil.getInstance(this)
        intent = getIntent()

        if (this.intent.hasExtra("input_type")) {
            this.mType = this.intent.extras.get("input_type") as FrameworkConstant.passwordInputType
            util.passwordInputType = this.mType
        }

        // 업데이트로 인한 초기화 (v4 비밀번호 4자리 -> 6자리 변경이슈)
        if (isOlderVersionPassword()) {
            util.passwordInputType = FrameworkConstant.passwordInputType.FIRST_INPUT
        }

        type = util.passwordInputType


//        this.authFingerprint = AuthFingerprint()

//        Reprint.initialize(this.applicationContext)

//        if (checkDeviceSpec() && type != FrameworkConstant.passwordInputType.FIRST_INPUT) {
//            Reprint.authenticate(this.authFingerprint)
//        }

        window.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)
        window.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))



        arrPassword = ArrayList()
        arrPreviousPassword = ArrayList()

        val typeface = Typeface.createFromAsset(this.assets, "fonts/Quivira.otf")

        val backspaceBtn = findViewById(R.id.button_backspace) as Button
        backspaceBtn.typeface = typeface




        when (type) {
            FrameworkConstant.passwordInputType.FIRST_INPUT -> {
                util.passwordInputType = FrameworkConstant.passwordInputType.FIRST_INPUT
            }
            FrameworkConstant.passwordInputType.CONFIRM_INPUT -> {
                util.passwordInputType = FrameworkConstant.passwordInputType.FIRST_INPUT
            }
            FrameworkConstant.passwordInputType.UNLOCK_INPUT -> {
                util.passwordInputType = FrameworkConstant.passwordInputType.UNLOCK_INPUT
            }
            FrameworkConstant.passwordInputType.UNLOCK_FAIL_RE_INPUT -> {
                util.passwordInputType = FrameworkConstant.passwordInputType.UNLOCK_INPUT
            }
            FrameworkConstant.passwordInputType.CHANGE_FIRST_INPUT -> {
                //                util.setPasswordInputType(UNLOCK_INPUT);
            }
            FrameworkConstant.passwordInputType.CHANGE_CONFIRM_INPUT -> {
                //                util.setPasswordInputType(UNLOCK_INPUT);
            }
        }

        //        현재 상태에 따라 화면을 다르게 보여준다.
        // this.textRewrite()
    }


    public override fun onPause() {
        super.onPause()


        val util = PreferenceUtil.getInstance(this)
        val type: FrameworkConstant.passwordInputType
        type = util.passwordInputType
        when (type) {
            FrameworkConstant.passwordInputType.FIRST_INPUT -> {
                util.passwordInputType = FrameworkConstant.passwordInputType.FIRST_INPUT
            }
            FrameworkConstant.passwordInputType.CONFIRM_INPUT -> {
                util.passwordInputType = FrameworkConstant.passwordInputType.FIRST_INPUT
            }
            FrameworkConstant.passwordInputType.UNLOCK_INPUT -> {
                util.passwordInputType = FrameworkConstant.passwordInputType.UNLOCK_INPUT
            }
            FrameworkConstant.passwordInputType.UNLOCK_FAIL_RE_INPUT -> {
                util.passwordInputType = FrameworkConstant.passwordInputType.UNLOCK_INPUT
            }
            FrameworkConstant.passwordInputType.CHANGE_FIRST_INPUT -> {
                util.passwordInputType = FrameworkConstant.passwordInputType.UNLOCK_INPUT
            }
            FrameworkConstant.passwordInputType.CHANGE_CONFIRM_INPUT -> {
                util.passwordInputType = FrameworkConstant.passwordInputType.UNLOCK_INPUT
            }
        }
    }

    public override fun onResume() {
        super.onResume()
        //checkFingerprintEnable()

    }

    private fun checkFingerprintEnable() {

        if (checkDeviceSpec()) {

            val p = this.context.getSharedPreferences("fingerprint", Context.MODE_PRIVATE)
            val enable = p.getBoolean("fingerprint", true)

            if (enable) {
                //문구 변경
                if (type == FrameworkConstant.passwordInputType.FIRST_INPUT) {
                    description?.text = "암호를 입력해 주세요."
                } else {
                    description?.text = "지문이나 암호를 입력해 주세요."
                    //지문입력은 암호를 입력하지 않은 경우에는 사용하지 않는다.
//                    Reprint.authenticate(this.authFingerprint)
                }

            } else {
//                Reprint.cancelAuthentication()
                //문구변경
                description?.text = "암호를 입력해 주세요."
            }
        } else {
            description?.text = "암호를 입력해 주세요."
            if (checkDeviceSpec()) {
//                Reprint.cancelAuthentication()
            }
        }
    }

    fun textRewrite() {
        val util = PreferenceUtil.getInstance(this)
        val inputType: FrameworkConstant.passwordInputType
        inputType = util.passwordInputType


        when (inputType) {
            FrameworkConstant.passwordInputType.FIRST_INPUT -> {
                title?.text = "암호입력"
                description?.text = "암호를 입력해 주세요."
            }
            FrameworkConstant.passwordInputType.CONFIRM_INPUT -> {
                title?.text = "암호 입력"
                description?.text = "확인을 위해 한 번 더 입력해 주세요"
            }
            FrameworkConstant.passwordInputType.UNLOCK_INPUT -> {
                title?.text = "암호입력"
                description?.text = "지문이나 암호를 입력해 주세요."
            }
            FrameworkConstant.passwordInputType.UNLOCK_FAIL_RE_INPUT -> {
                title?.text = "암호입력"
                description?.text = "암호가 틀렸습니다. 다시 입력해 주세요"
            }
            FrameworkConstant.passwordInputType.CHANGE_FIRST_INPUT -> {
                title?.text = "새로운 암호입력"
                description?.text = "새로운 암호를 입력해 주세요."
            }
            FrameworkConstant.passwordInputType.CHANGE_CONFIRM_INPUT -> {
                title?.text = "새로운 암호 재입력"
                description?.text = "확인을 위해 한 번 더 입력해 주세요."
            }
        }
    }


    override fun onBackPressed() {

        val util = PreferenceUtil.getInstance(this)

        val type: FrameworkConstant.passwordInputType
        type = util.passwordInputType

        when (type) {
            FrameworkConstant.passwordInputType.FIRST_INPUT -> {
                util.passwordInputType = FrameworkConstant.passwordInputType.FIRST_INPUT
                super.onBackPressed()
                programShutdown()
            }
            FrameworkConstant.passwordInputType.CONFIRM_INPUT -> {
                util.passwordInputType = FrameworkConstant.passwordInputType.FIRST_INPUT
                super.onBackPressed()
                programShutdown()
            }
            FrameworkConstant.passwordInputType.UNLOCK_INPUT -> {
                this.programShutdown()
            }
            FrameworkConstant.passwordInputType.UNLOCK_FAIL_RE_INPUT -> {
                util.passwordInputType = FrameworkConstant.passwordInputType.UNLOCK_INPUT
                this.programShutdown()
            }
            FrameworkConstant.passwordInputType.CHANGE_FIRST_INPUT -> {
                util.passwordInputType = FrameworkConstant.passwordInputType.UNLOCK_INPUT
                util.setUnlockTime()
                super.onBackPressed()
            }
            FrameworkConstant.passwordInputType.CHANGE_CONFIRM_INPUT -> {
                util.passwordInputType = FrameworkConstant.passwordInputType.UNLOCK_INPUT
                util.setUnlockTime()
                super.onBackPressed()
            }
        }
    }

    private fun programShutdown() {
        this.moveTaskToBack(true)
        this.finish()
        android.os.Process.killProcess(android.os.Process.myPid())
        System.exit(0)
    }

    fun isValidNumber(pw:String):Boolean {
        print(pw)
        val pwRegEx = "^(?!.*?(?:0(?:12|98)|123|234|3(?:45|21)|4(?:56|32)|5(?:67|43)|6(?:78|54)|7(?:89|65)|876|987))(?!.*?(.)\\1{2})[0-9]{6}".toRegex()

        return pwRegEx.matches(pw)
    }


    fun numpadClick(view: View) {

        val num = Integer.parseInt(view.tag.toString())
        var intputSize = 0

        val arrPassword = arrPassword ?: return
        if (arrPassword.isEmpty() == false) {
            intputSize = arrPassword.size
        }

        if (num == -1) {
            // password 하나 지움
            if (intputSize > 0) {
                arrPassword.removeAt(arrPassword.size - 1)
            }
        } else {
            // password 하나 추가
            if (intputSize < 6) {
                arrPassword.add(arrPassword.size, num)
            }
        }

        this.changingPasswordViews()

        if (arrPassword.size == 6) {
            val util = PreferenceUtil.getInstance(this)

            val type: FrameworkConstant.passwordInputType
            type = util.passwordInputType

            this.printPassword()

            when (type) {

                FrameworkConstant.passwordInputType.FIRST_INPUT -> {
                    val pw = arrPassword.reduce { acc, any -> "${acc}${any}" } as String

                    if(this.isValidNumber(pw) == false){
                        arrPassword.clear()
                        //textRewrite()
                        this.title?.text = "암호입력"
                        this.description?.text = "연속된 암호를 사용할 수 없습니다. 다시 입력해 주세요"
                        this.lockTheScreen()
                        changingPasswordViews()
                        return;
                    }


                    util.passwordInputType = FrameworkConstant.passwordInputType.CONFIRM_INPUT
                    //textRewrite()
                    arrPreviousPassword?.clear()
                    arrPreviousPassword?.addAll(arrPassword)

                    arrPassword.clear()

                    SystemClock.sleep(200)
                    changingPasswordViews()

                }
                FrameworkConstant.passwordInputType.CONFIRM_INPUT -> {

                    if (this.comparePasswords()) {

                        util.password = this.arrPassword
                        util.passwordInputType = FrameworkConstant.passwordInputType.UNLOCK_INPUT
                        util.setUnlockTime()

                        changingPasswordViews()

                        SystemClock.sleep(200)
                        finish()
                    } else {
                        util.passwordInputType = FrameworkConstant.passwordInputType.FIRST_INPUT
                        this.title?.text = "암호입력"
                        this.description?.text = "암호가 틀렸습니다. 다시 입력해 주세요."
                        this.lockTheScreen()

                        this.arrPassword?.clear()
                        this.arrPreviousPassword?.clear()

                        changingPasswordViews()
                        SystemClock.sleep(200)
                        finish()
                    }


                }
                FrameworkConstant.passwordInputType.UNLOCK_INPUT -> {

                    if (this.comparePasswordsWithStorage()) {
                        util.passwordInputType = FrameworkConstant.passwordInputType.UNLOCK_INPUT
                        util.setUnlockTime()
                        this.changingPasswordViews()

                        SystemClock.sleep(200)
                        finish()

                    } else {
                        util.passwordInputType = FrameworkConstant.passwordInputType.UNLOCK_FAIL_RE_INPUT
                        this.arrPassword?.clear()

                        this.title?.text = "암호입력"
                        this.description?.text = "암호가 틀렸습니다 다시 입력해 주세요."
                        this.lockTheScreen()
                        changingPasswordViews()

                    }

                }
                FrameworkConstant.passwordInputType.UNLOCK_FAIL_RE_INPUT -> {

                    if (this.comparePasswordsWithStorage()) {
                        util.passwordInputType = FrameworkConstant.passwordInputType.UNLOCK_INPUT
                        changingPasswordViews()
                        util.setUnlockTime()

                        SystemClock.sleep(200)
                        finish()
                    } else {
                        util.passwordInputType = FrameworkConstant.passwordInputType.UNLOCK_FAIL_RE_INPUT
                        this.arrPassword?.clear()
                        this.lockTheScreen()

                        changingPasswordViews()
                    }

                }
                FrameworkConstant.passwordInputType.CHANGE_FIRST_INPUT -> {

                    util.passwordInputType = FrameworkConstant.passwordInputType.CHANGE_CONFIRM_INPUT
                    //this.textRewrite()
                    arrPreviousPassword?.clear()
                    arrPreviousPassword?.addAll(arrPassword)
                    arrPassword.clear()

                    changingPasswordViews()

                }
                FrameworkConstant.passwordInputType.CHANGE_CONFIRM_INPUT -> {
                    //this.arrPreviousPassword = util.getPassword();
                    if (this.comparePasswords()) {

                        util.password = this.arrPassword

                        changingPasswordViews()
                        util.setUnlockTime()
                        Log.i("새로운 암호 저장", "새로운 암호 저장")
                        SystemClock.sleep(200)
                        util.passwordInputType = FrameworkConstant.passwordInputType.UNLOCK_INPUT
                        
                        val intent = Intent()
                        setResult(RESULT_OK, intent)
                        finish()
                    } else {
                        util.passwordInputType = FrameworkConstant.passwordInputType.CHANGE_FIRST_INPUT

                        this.arrPassword?.clear()
                        this.arrPreviousPassword?.clear()

                        this.title?.text = "새로운 암호입력"
                        this.description?.text = "암호가 틀렸습니다 새로운 암호를 입력해 주세요."
                        this.lockTheScreen()

                        changingPasswordViews()
                    }
                }
            }


        }

    }

    private fun comparePasswords(): Boolean {
        var isEqual: Boolean = false

        val arrPreviousPassword = arrPreviousPassword ?: return false
        val arrPassword = arrPassword ?: return false
        for (a in arrPreviousPassword.indices) {

            val pw1 = arrPreviousPassword[a] as Int
            val pw2 = arrPassword[a] as Int

            if (pw1 == pw2) {
                isEqual = true
            } else {
                isEqual = false
                return isEqual
            }
        }
        return isEqual
    }

    fun comparePasswordsWithStorage(): Boolean {

        var isEncEqual: Boolean = false
        val aes = AES()
        val util = PreferenceUtil.getInstance(this)
        val arrPassword = arrPassword ?: return false
        for (a in arrPassword.indices) {

            try {
                var pw1 = AES.Encrypt(arrPassword[a].toString())
                pw1 = pw1.replace("\n", "") // 암호화를 하고 나면 캐리지리턴이 붙는다 -_-;
                val pw2 = util.getPasswordByIndex(a)
                if (pw1 == pw2) {
                    isEncEqual = true
                } else {
                    isEncEqual = false
                    return isEncEqual
                }

            } catch (e: Exception) {
                e.printStackTrace()
            }


        }

        return isEncEqual!!
    }


    private fun changingPasswordViews() {

        //        final Handler handler = new Handler(Looper.getMainLooper());
        Thread(Runnable {
            runOnUiThread {
                val num = arrPassword?.size
                val passwordView1 = findViewById<View>(R.id.password_view1)
                val passwordView2 = findViewById<View>(R.id.password_view2)
                val passwordView3 = findViewById<View>(R.id.password_view3)
                val passwordView4 = findViewById<View>(R.id.password_view4)
                val passwordView5 = findViewById<View>(R.id.password_view5)
                val passwordView6 = findViewById<View>(R.id.password_view6)
                when (num) {
                    0 -> {
                        passwordView1?.setBackgroundResource(R.drawable.password_shape)
                        passwordView2?.setBackgroundResource(R.drawable.password_shape)
                        passwordView3?.setBackgroundResource(R.drawable.password_shape)
                        passwordView4?.setBackgroundResource(R.drawable.password_shape)
                        passwordView5?.setBackgroundResource(R.drawable.password_shape)
                        passwordView6?.setBackgroundResource(R.drawable.password_shape)
                    }
                    1 -> {
                        passwordView1?.setBackgroundResource(R.drawable.password_shape_black)
                        passwordView2?.setBackgroundResource(R.drawable.password_shape)
                        passwordView3?.setBackgroundResource(R.drawable.password_shape)
                        passwordView4?.setBackgroundResource(R.drawable.password_shape)
                        passwordView5?.setBackgroundResource(R.drawable.password_shape)
                        passwordView6?.setBackgroundResource(R.drawable.password_shape)
                    }
                    2 -> {
                        passwordView1?.setBackgroundResource(R.drawable.password_shape_black)
                        passwordView2?.setBackgroundResource(R.drawable.password_shape_black)
                        passwordView3?.setBackgroundResource(R.drawable.password_shape)
                        passwordView4?.setBackgroundResource(R.drawable.password_shape)
                        passwordView5?.setBackgroundResource(R.drawable.password_shape)
                        passwordView6?.setBackgroundResource(R.drawable.password_shape)
                    }
                    3 -> {
                        passwordView1?.setBackgroundResource(R.drawable.password_shape_black)
                        passwordView2?.setBackgroundResource(R.drawable.password_shape_black)
                        passwordView3?.setBackgroundResource(R.drawable.password_shape_black)
                        passwordView4?.setBackgroundResource(R.drawable.password_shape)
                        passwordView5?.setBackgroundResource(R.drawable.password_shape)
                        passwordView6?.setBackgroundResource(R.drawable.password_shape)
                    }
                    4 -> {
                        passwordView1?.setBackgroundResource(R.drawable.password_shape_black)
                        passwordView2?.setBackgroundResource(R.drawable.password_shape_black)
                        passwordView3?.setBackgroundResource(R.drawable.password_shape_black)
                        passwordView4?.setBackgroundResource(R.drawable.password_shape_black)
                        passwordView5?.setBackgroundResource(R.drawable.password_shape)
                        passwordView6?.setBackgroundResource(R.drawable.password_shape)
                    }
                    5 -> {
                        passwordView1?.setBackgroundResource(R.drawable.password_shape_black)
                        passwordView2?.setBackgroundResource(R.drawable.password_shape_black)
                        passwordView3?.setBackgroundResource(R.drawable.password_shape_black)
                        passwordView4?.setBackgroundResource(R.drawable.password_shape_black)
                        passwordView5?.setBackgroundResource(R.drawable.password_shape_black)
                        passwordView6?.setBackgroundResource(R.drawable.password_shape)
                    }
                    6 -> {
                        passwordView1?.setBackgroundResource(R.drawable.password_shape_black)
                        passwordView2?.setBackgroundResource(R.drawable.password_shape_black)
                        passwordView3?.setBackgroundResource(R.drawable.password_shape_black)
                        passwordView4?.setBackgroundResource(R.drawable.password_shape_black)
                        passwordView5?.setBackgroundResource(R.drawable.password_shape_black)
                        passwordView6?.setBackgroundResource(R.drawable.password_shape_black)
                    }
                }
            }
        }).start()

    }

    private fun lockTheScreen() {

        val vibe = getSystemService(VIBRATOR_SERVICE) as Vibrator
        val pattern = longArrayOf(500)
        vibe.vibrate(pattern, 0)
        vibe.vibrate(500)
    }

    public fun unlockTheScreen() {
        this.finish()
    }


    private fun printPassword() {
        AnkoLogger("saved Password : ").debug { this.arrPreviousPassword }
    }

    //지문가능한 기기 혹은 지문이 등록되어있는지 체크
    private fun checkDeviceSpec(): Boolean {
        return false
//        val fingerprintFlag = Reprint.isHardwarePresent()
//        val hasRegisterdFlag = Reprint.hasFingerprintRegistered()
//        return fingerprintFlag && hasRegisterdFlag
    }

    /*
    inner class AuthFingerprint : AuthenticationListener {

        override fun onSuccess(moduleTag: Int) {
            //지문인식 성공
            val util = PreferenceUtil.getInstance(context)
            util.setUnlockTime()
            finish()
        }

        override fun onFailure(failureReason: AuthenticationFailureReason, fatal: Boolean, errorMessage: CharSequence, moduleTag: Int, errorCode: Int) {
            //지문인식 실패
            fingerPrintCount++

            if (fingerPrintCount > 2) {
                fingerPrintCount = 0
                lockTheScreen()
                Reprint.cancelAuthentication()
                description?.text = "암호를 입력해 주세요."
            } else {
                lockTheScreen()
                description?.text = "지문인식에 실패하였습니다."
            }
        }
    }
    */

    fun isOlderVersionPassword():Boolean {
        val util: PreferenceUtil = PreferenceUtil.getInstance(this)
        val count: Int = arrayListOf(0, 1, 2, 3, 4, 5).map {
            util.getPasswordByIndex(it)
        }
        .filterNotNull()
        .filterNot { it == "" }
        .count()
        return count == 4
    }

}