package com.lemonhc.mplus.mcare_plus.activity

import android.annotation.SuppressLint
import android.app.Activity
import android.app.ActivityManager
import android.content.Context
import android.content.Intent
import android.nfc.NfcAdapter.EXTRA_TAG
import android.nfc.Tag
import android.os.Build
import android.os.Bundle
import android.os.Handler
import android.os.Message
import android.util.Log
import android.view.KeyEvent
import android.view.View
import android.view.WindowManager
import android.webkit.JavascriptInterface
import android.webkit.WebSettings
import android.webkit.WebView
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import com.google.gson.Gson
import com.lemonhc.mplus.MPlusConstants
import com.lemonhc.mplus.MPlusConstants.JAVASCRIPT_INTERFACE
import com.lemonhc.mplus.MPlusConstants.SERVICE_START_ADDR
import com.lemonhc.mplus.MPlusConstants.SERVICE_URL
import com.lemonhc.mplus.MPlusConstants.USE_LOCK_SCREEN
import com.lemonhc.mplus.Sign.SignWrapper
import com.lemonhc.mplus.barcode.BarcodeEventHandler
import com.lemonhc.mplus.barcode.BarcodeEventListener
import com.lemonhc.mplus.classes.MessageClass
import com.lemonhc.mplus.framework.constant.FrameworkConstant
import com.lemonhc.mplus.framework.util.PreferenceUtil
import com.lemonhc.mplus.framework.util.kotlinExtension.isCaptureFlag
import com.lemonhc.mplus.framework.util.kotlinExtension.versionCheck
import com.lemonhc.mplus.mcare_plus.R
import com.lemonhc.mplus.mcare_plus.activity.Util.Util
import com.lemonhc.mplus.mcare_plus.activity.lockScreen.LockScreenActivity
import com.lemonhc.mplus.mcare_plus.activity.webView.CustomWebChromeClient
import com.lemonhc.mplus.mcare_plus.activity.webView.CustomWebViewClient
import com.lemonhc.mplus.mcare_plus.activity.webView.WebViewCallFunctions
import kotlinx.android.synthetic.main.activity_main.*
import java.lang.Long.parseLong
import java.lang.ref.WeakReference


class MainActivity: AppCompatActivity(), NfcManager.TagListener , BarcodeEventListener{

    override fun onEvent(result: String?) {
        val callback = if (result != null) {
            "javascript:barcodeCallback(\"$result\")"
        } else {
            "javascript:barcodeCallback('{\"success\": \"false\", \"result\": \"\"}')"
        }
        webView!!.post{webView!!.loadUrl(callback)}
    }
    
    private var webView: WebView? = null
    private var nfc:NfcManager? = null
    private var isRunning: Boolean = false
    


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

        // 챗봇이벤트 리스너 사용등록
        BarcodeEventHandler.addListener(this)

        setContentView(R.layout.activity_main).run {
            webView = findViewById(R.id.webview)
        }
        if (!isCaptureFlag) {
            window.addFlags(WindowManager.LayoutParams.FLAG_SECURE)
        }
        setWebView(this, webView)
        this.webView?.loadUrl("$SERVICE_URL$SERVICE_START_ADDR")

//        this.webView?.loadUrl("https://google.com/")

        nfc = NfcManager(this)
        Log.e("MainActivity", "onCreate!!")
    }


    public override fun onStart() {
        super.onStart()
        Log.e("MainActivity", "onStart!!")
    }

    public override fun onDestroy() {
        nfc = null
        isRunning = false
        super.onDestroy()
    }

    public override fun onPause() {
        nfc?.onPause()
        isRunning = true
        Log.e("MainActivity", "onPause!!")
        super.onPause()

    }

    public override fun onResume() {
        super.onResume()
        Log.e("MainActivity", "onResume!!")
        nfc?.onResume(this)

        if (!USE_LOCK_SCREEN) {
            return
        }
        if (isVisibleExWebView) {
            isVisibleExWebView = false
            return
        }
        if (isVisibleQrcode) {
            isVisibleQrcode = false
            return
        }
        if (isVisibleCamera) {
            isVisibleCamera = false
            return
        }
        
        if (intent.hasExtra("lock_yn")) {
            val lockYn = intent.extras.getBoolean("lock_yn")
            if (lockYn) {
                lockScreenCall()
            } else {
                intent.putExtra("lock_yn", false)
            }
        } else {
            lockScreenCall()
        }
        //버전체크
        if (MPlusConstants.IS_PASS_VERSION_CHECK){

        } else{
            this.versionCheck()
        }


    }

    override fun onNewTagIntent(intent: Intent?) {
        val tag: Tag? = intent?.getParcelableExtra<Tag>(EXTRA_TAG)
//        val tagId: ByteArray? = tag?.id
//        Log.e("test","### onNewTagIntent. ${tagId.toString()}")

//        val isoDep: NfcA? = NfcA.get(tag)

        val myTagId = nfc?.getCardId(nfc?.attachCard(intent))

        val idArray:List<String> = myTagId!!.chunked(2).reversed()

        val sb = StringBuilder()
        for (x in idArray) {
            sb.append(x)
        }
        var reversedString:String? = sb.toString()
//        reversedString = "8A31FF04"
        var decimalString = parseLong(reversedString, 16)


        Log.e("test","### decimalString. $decimalString")


        runOnUiThread {
            Toast.makeText(this, "TAG ID: $decimalString", Toast.LENGTH_SHORT).show()
        }

        val callback = if (myTagId != null) {
            "javascript:nfctagCallback(\"$decimalString\")"
        } else {
            "javascript:nfctagCallback({\"success\": \"false\", \"result\": \"\")"
        }
        webView!!.post{webView!!.loadUrl(callback)}

    }

    //String을 size 길이로 잘라서 리스트에 담아서 리턴해주는 함수.
    fun String.chunked(size: Int): List<String> {
        val nChunks = length / size
        return (0 until nChunks).map { substring(it * size, (it + 1) * size) }
    }



    private fun lockScreenCall() {
        if (!isRunning) {
            val util = PreferenceUtil.getInstance(this)
            //현재시간이 락을 해제하고 1초가 지난경우에만 락스크린을 보여준다.
            //초기값은 -1
            if (util.unlockTime + 1000 < System.currentTimeMillis() || util.unlockTime.toInt() == -1) {
                val intent = Intent(this, LockScreenActivity::class.java)
                startActivity(intent)
            }
        }
    }

    companion object {
        var isVisibleExWebView:Boolean = false
        var isVisibleQrcode:Boolean = false
        var isVisibleCamera:Boolean = false

        @SuppressLint("JavascriptInterface")
        fun setWebView(activity:Activity, view: WebView?) {
            view?.apply {
                settings.builtInZoomControls = true
                settings.displayZoomControls = false //우측하단 줌 컨트롤버튼 디스플레이 유무
                settings.setSupportZoom(true)
                settings.javaScriptCanOpenWindowsAutomatically = true
                settings.javaScriptEnabled = true
                settings.useWideViewPort = true
                settings.loadsImagesAutomatically = true
                settings.blockNetworkImage = false
                settings.setSupportMultipleWindows(false)
                settings.allowFileAccess = true
                settings.domStorageEnabled = true
                settings.saveFormData = false
                settings.setAppCacheEnabled(false)
                settings.defaultTextEncodingName = "UTF-8"
                settings.cacheMode = WebSettings.LOAD_NO_CACHE
                settings.mixedContentMode = WebSettings.MIXED_CONTENT_ALWAYS_ALLOW
                setWebViewClient(CustomWebViewClient(context))
                setWebChromeClient(CustomWebChromeClient(context))
                addJavascriptInterface(activity, JAVASCRIPT_INTERFACE)
                isHorizontalScrollBarEnabled = false
                isVerticalScrollBarEnabled = false
                isScrollContainer = false
                requestFocus(View.FOCUS_DOWN)
                isFocusable = true
                isFocusableInTouchMode = true

                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { // 웹뷰 디버그 기능 추가
                    WebView.setWebContentsDebuggingEnabled(true)
                }
                setOnKeyListener { _, code, event ->
                    if(event.action == KeyEvent.ACTION_DOWN && code == KeyEvent.KEYCODE_BACK && !MPlusConstants.IS_BACK_BUTTON_DISABLE){
                        loadUrl("javascript:triggerBackBtn()")
                    }
                    return@setOnKeyListener true
                }
            } ?: return
        }

        fun checkInstallPACS(context: Context, packageName: String): Boolean {
            val mainIntent = Intent(Intent.ACTION_MAIN, null)
            mainIntent.addCategory(Intent.CATEGORY_LAUNCHER)
            val pm = context.packageManager
            val installedApps = pm.queryIntentActivities(mainIntent, 0)

            for (ri in installedApps) {
                Log.d("tag", ri.activityInfo.packageName)

                if (packageName == ri.activityInfo.packageName) {
                    Log.i("test", "infinitt PACS app installed")
                    return true
                }
            }
            return false
        }
    }

    @JavascriptInterface
    @Throws(Exception::class)
    fun toNative(jsonStr: String) {
        val msgClass = Gson().fromJson(jsonStr, MessageClass::class.java)
        val type = FrameworkConstant.msg_types.getEnum(msgClass.type) ?: throw Exception("type value is null.")
        when (type) {
            FrameworkConstant.msg_types.ERROR ->
                return
            FrameworkConstant.msg_types.COMMAND -> {
                val cls = WebViewCallFunctions(this, webview)
                cls.functionName = msgClass.functionType
                if (msgClass.value != null) {
                    cls.param = msgClass.value
                }
                Handler().post {
                    try {
                        val method = cls.javaClass.getDeclaredMethod(cls.functionName)
                        method.invoke(cls)
                    } catch (e: Exception) {
                        e.printStackTrace()
                    }
                }
            }
        }
    }

    @JavascriptInterface
    fun pacs(jsonStr: String) {
        val sendIntent = this.packageManager.getLaunchIntentForPackage("com.dbs.mplus.kunkuk")
        sendIntent.putExtra("my_text", jsonStr)
        this.startActivity(sendIntent)
    }

    @JavascriptInterface
    fun showToast(msg: String) {
        Toast.makeText(this, msg, Toast.LENGTH_SHORT).show()
    }

    class OuterClass {

        // In the outer class, instantiate a WeakReference to the outer class.
        private val outerClass = WeakReference<OuterClass>(this)

        // Pass the WeakReference object to the outer class to your Handler
        // when you instantiate the Handler
        private val mMyHandler = MyHandler(outerClass)

        private var outerVariable: String = "OuterClass"

        private fun outerMethod() {

        }

        // Declare the Handler as a static class.
        class MyHandler(private val outerClass: WeakReference<OuterClass>) : Handler() {

            override fun handleMessage(msg: Message?) {
                // Your logic code here.
                // ...

                // Make all references to members of the outer class
                // using the WeakReference object.
                outerClass.get()?.outerVariable
                outerClass.get()?.outerMethod()
            }
        }
    }

}
