package com.mime.dualscreenview.activity

import android.app.ActivityOptions
import android.content.Context
import android.content.DialogInterface
import android.content.Intent
import android.content.pm.ActivityInfo
import android.content.res.Configuration
import android.graphics.Color
import android.hardware.display.DisplayManager
import android.os.Build
import android.os.Bundle
import android.util.Log
import android.view.KeyEvent
import android.view.View
import android.view.View.*
import android.webkit.WebView
import android.widget.ArrayAdapter
import android.widget.Button
import android.widget.ImageButton
import android.widget.LinearLayout
import android.widget.ProgressBar
import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.widget.AppCompatButton
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.view.updateLayoutParams
import com.google.gson.Gson
import com.lge.display.DisplayManagerHelper
import com.mime.dualscreenview.R
import com.mime.dualscreenview.common.Blog
import com.mime.dualscreenview.dto.BookPageInfos
import com.mime.dualscreenview.dto.LastInfo
import com.mime.dualscreenview.view.PagedTextLayout
import com.mime.dualscreenview.view.PagedTextViewInterface
import com.mime.dualscreenview.view.TouchArea
import com.mime.dualscreenview.webcontents.BaseWebContentsViewer
import com.mime.dualscreenview.webcontents.MainControllInterface
import com.mime.dualscreenview.webcontents.contentsinfo.Booktoki
import com.mime.dualscreenview.webcontents.contentsinfo.GotoSomeWhere
import io.realm.kotlin.Realm
import io.realm.kotlin.RealmConfiguration
import io.realm.kotlin.ext.copyFromRealm
import io.realm.kotlin.ext.query


class Intro : Base() , MainControllInterface, PagedTextViewInterface {

    private var displayManagerHelper: DisplayManagerHelper? = null

    // This callbacks where receive events from the cover
    private var coverDisplayCallback: MainCoverDisplayCallback? = null
    private var smartCoverCallback: MainSmartCoverCallback? = null

    // Save previous state of dual screens
    private var prevDualScreenState = DisplayManagerHelper.STATE_UNMOUNT

    private var isLGDualScreen: Boolean = false
    private lateinit var mBaseWebContentsViewer : BaseWebContentsViewer
    var lastInfo : LastInfo? = null

    val colors = arrayOf<Array<String>>(
        arrayOf<String>("#E1F5FE", "#263238"),
        arrayOf<String>("#F0F4C3", "#37474F"),
        arrayOf<String>("#ECEFF1", "#455A64"),
        arrayOf<String>("#E0F7FA", "#263238"),
        arrayOf<String>("#F5F5F5", "#263238"),
        arrayOf<String>("#ECEFF1", "#263238"),
        arrayOf<String>("#F8BBD0", "#263238"),
        arrayOf<String>("#E6EE9C", "#455A64"),
        arrayOf<String>("#CFD8DC", "#455A64"),
        arrayOf<String>("#FFF59D", "#37474F")
    )

    override fun onConfigurationChanged(newConfig: Configuration) {
        super.onConfigurationChanged(newConfig)
        Blog.LOGD(log= "onConfigurationChanged ${this::class.java.name} >> newConfig ${newConfig}")
        mBaseWebContentsViewer.webview.reload()
    }
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        Blog.LOGD(log= "onCreate ${this::class.java.name} >> savedInstanceState ${savedInstanceState}")

        setContentView(R.layout.intro)
        mBaseWebContentsViewer = BaseWebContentsViewer(findViewById<WebView>(R.id.menu_web),this)
        try {
            // Try to construct the DisplayMangerHelper.
            // If it isn't successful, this device isn't LG dual screens
            displayManagerHelper = DisplayManagerHelper(applicationContext)
            coverDisplayCallback = MainCoverDisplayCallback()
            smartCoverCallback = MainSmartCoverCallback()

            // Register the callbacks for covers
            displayManagerHelper?.registerCoverDisplayEnabledCallback(
                applicationContext.packageName,
                coverDisplayCallback
            )
            displayManagerHelper?.registerSmartCoverCallback(smartCoverCallback)
            isLGDualScreen = true
        } catch (e: Exception) {
            isLGDualScreen = false
            Log.e(TAG, "This device isn't LG dual screens", e)
        }

        findViewById<ImageButton>(R.id.btn_list).setOnClickListener { v ->
            mBaseWebContentsViewer?.findListItem {result ->
                var infos = Gson().fromJson(result, BookPageInfos::class.java)
                showList(infos)
            }
        }

        findViewById<View>(R.id.btn_rotate).setOnClickListener { v->
           switcvhOrient()
        }
        findViewById<View>(R.id.btn_setting).setOnClickListener { v->
            showStyleList()
        }
        findViewById<View>(R.id.btn_home).setOnClickListener { v->
            mBaseWebContentsViewer.loadContents(Booktoki())
        }

        val config = RealmConfiguration.Builder(setOf(LastInfo::class)).schemaVersion(1)
            .build()
        val realm = Realm.open(config)


        try {
            lastInfo = realm?.query<LastInfo>()?.find()?.last()?.copyFromRealm()
        } catch (e : Exception) {

        }
        if (lastInfo != null) {
            setRequestedOrientation(lastInfo!!.displayOrientation);
            mBaseWebContentsViewer.loadLastInfo(lastInfo!!)
        } else {
            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
            mBaseWebContentsViewer.loadContents(Booktoki())
        }
        Blog.LOGD(log ="Successfully opened realm: ${realm.configuration.name}")
        realm.close()
    }
    fun switcvhOrient(){
        val windowManager = getSystemService(WINDOW_SERVICE)
        val configuration: Configuration = getResources().getConfiguration()
        setRequestedOrientation(
            if(configuration.orientation == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT) { ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE }
            else {ActivityInfo.SCREEN_ORIENTATION_PORTRAIT}
        )
    }

    fun showList(infos: BookPageInfos) {
        val builderSingle: AlertDialog.Builder = AlertDialog.Builder(this@Intro)
        builderSingle.setTitle("Select One Name:-")
        val arrayAdapter =
            ArrayAdapter<String>(this@Intro, android.R.layout.select_dialog_singlechoice)
        arrayAdapter.addAll(infos.getTitleArray())


        builderSingle.setNegativeButton("cancel",
            DialogInterface.OnClickListener { dialog, which -> dialog.dismiss() })

        builderSingle.setAdapter(arrayAdapter,
            DialogInterface.OnClickListener { dialog, which ->
                val strName = arrayAdapter.getItem(which)
                val builderInner: AlertDialog.Builder = AlertDialog.Builder(this@Intro)
                builderInner.setMessage(strName)
                builderInner.setTitle("Your Selected Item is")
                builderInner.setPositiveButton("Ok",
                    DialogInterface.OnClickListener { dialog, which -> dialog.dismiss() })
                builderInner.show()
            })
        var ddddd= builderSingle.create()
        ddddd.setOnShowListener { d->
            (d as? AlertDialog)?.let{
                it.listView?.smoothScrollToPosition(currentChapter)
            }
        }

        ddddd.show()
    }

    fun showStyleList() {
        val builderSingle: AlertDialog.Builder = AlertDialog.Builder(this@Intro)
        builderSingle.setTitle("Select One Name:-")
        val arrayAdapter =
            ArrayAdapter<String>(this@Intro, android.R.layout.select_dialog_singlechoice)
        var styleNum = 1;
        for (a in colors) {
            arrayAdapter.add("스타일 ${styleNum}")
            styleNum = styleNum.inc()
        }


        builderSingle.setNegativeButton("cancel",
            DialogInterface.OnClickListener { dialog, which -> dialog.dismiss() })

        builderSingle.setAdapter(arrayAdapter,
            DialogInterface.OnClickListener { dialog, which ->
                val color = colors.get(which)
                val builderInner: AlertDialog.Builder = AlertDialog.Builder(this@Intro)
                builderInner.setMessage("스타일 ${which + 1}")

                builderInner.setTitle("Your Selected Item is")
                builderInner.setPositiveButton("Ok",
                    DialogInterface.OnClickListener { dialog, which -> dialog.dismiss()
                        pg?.setColorStyle(color)
                        findViewById<View>(R.id.intro_bg).setBackgroundColor(Color.parseColor(color.get(1)))
                    })
                builderInner.show()
            })
        var ddddd= builderSingle.create()
        ddddd.setOnShowListener { d->
            (d as? AlertDialog)?.let{
                it.listView?.smoothScrollToPosition(currentChapter)
            }
        }

        ddddd.show()
    }


    override fun onDestroy() {
        // Remove all callbacks when this activity is destroyed
        displayManagerHelper?.unregisterCoverDisplayEnabledCallback(applicationContext.packageName)
        displayManagerHelper?.unregisterSmartCoverCallback(smartCoverCallback)
        super.onDestroy()
    }

    /**
     * Convert cover display states to string to serve for logging
     *
     * @param state is the value integer of state
     * @return a string for this state
     */
    private fun coverDisplayStateToString(state: Int): String {
        return when (state) {
            DisplayManagerHelper.STATE_UNMOUNT -> "STATE_UNMOUNT"
            DisplayManagerHelper.STATE_DISABLED -> "STATE_DISABLED"
            DisplayManagerHelper.STATE_ENABLED -> "STATE_ENABLED"
            else -> "UNKNOWN_STATE"
        }
    }

    /**
     * Convert smart cover display states to string to serve for logging
     *
     * @param state is the value integer of state
     * @return a string for this state
     */
    private fun smartCoverStateToString(state: Int): String {
        return when (state) {
            DisplayManagerHelper.STATE_COVER_OPENED -> "STATE_COVER_OPENED"
            DisplayManagerHelper.STATE_COVER_CLOSED -> "STATE_COVER_CLOSED"
            DisplayManagerHelper.STATE_COVER_FLIPPED_OVER -> "STATE_COVER_FLIPPED_OVER"
            else -> "UNKNOWN_STATE"
        }
    }

    /**
     * Navigate to the second screen.
     *
     * See more at https://developer.android.com/guide/topics/ui/foldables?#using_secondary_screens
     */
    private fun toSecondScreen(screenNumStr : String) {

        var screenNum = screenNumStr.toInt()
        // DisplayManager manages the properties of attached displays.
        val displayManager = getSystemService(Context.DISPLAY_SERVICE) as DisplayManager

        // List displays was attached
        val displays = displayManager.displays

        if (displays.size > screenNum) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                // Activity options are used to select the display screen.
                val options = ActivityOptions.makeBasic()
                // Select the display screen that you want to show the second activity
                options.launchDisplayId = displays[screenNum].displayId

                // To display on the second screen that your intent must be set flag to make
                // single task (combine FLAG_ACTIVITY_CLEAR_TOP and FLAG_ACTIVITY_NEW_TASK)
                // or you also set it in the manifest (see more at the manifest file)
                startActivity(
                    Intent(this@Intro, Main::class.java).apply {

                    },
                    options.toBundle()
                )
            }
        } else {
            Toast.makeText(this, "Not found the second screen", Toast.LENGTH_SHORT).show()
        }
    }

    private inner class MainCoverDisplayCallback : DisplayManagerHelper.CoverDisplayCallback() {
        override fun onCoverDisplayEnabledChangedCallback(state: Int) {
            displayManagerHelper?.coverDisplayState?.let {
                Log.i(TAG, "Current DualScreen Callback state: ${coverDisplayStateToString(it)}")
            }
            if (prevDualScreenState != state) {
                when (state) {
                    DisplayManagerHelper.STATE_UNMOUNT -> {
                        Log.i(TAG, "Changed DualScreen State to STATE_UNMOUNT")
                    }
                    DisplayManagerHelper.STATE_DISABLED -> {
                        Log.i(TAG, "Changed DualScreen State to  STATE_DISABLED")
                    }
                    DisplayManagerHelper.STATE_ENABLED -> {
//                        toSecondScreen()
                        Log.i(TAG, "Changed DualScreen State to  STATE_ENABLED")
                    }
                }
                prevDualScreenState = state
            }
        }
    }

    private inner class MainSmartCoverCallback : DisplayManagerHelper.SmartCoverCallback() {
        override fun onTypeChanged(type: Int) {
            Log.i(TAG, "SmartCoverCallback type: ${displayManagerHelper?.coverType}")
        }

        override fun onStateChanged(state: Int) {
            displayManagerHelper?.coverState?.let {
                Log.i(TAG, "Current SmartCoverCallback state: ${smartCoverStateToString(it)}")
            }
            when (state) {
                DisplayManagerHelper.STATE_COVER_OPENED -> {
                    Log.i(TAG, "Received SmartCoverCallback is STATE_COVER_OPENED")
                }
                DisplayManagerHelper.STATE_COVER_CLOSED -> {
                    Log.i(TAG, "Received SmartCoverCallback is STATE_COVER_CLOSED")
                }
                DisplayManagerHelper.STATE_COVER_FLIPPED_OVER -> {
                    Log.i(TAG, "Received SmartCoverCallback is STATE_COVER_FLIPPED_OVER")
                }
            }
        }
    }
    var pg : PagedTextLayout? = null;

    var onNextClickAction: GotoSomeWhere? = null
    override fun showNextBtn(find : Boolean , onClickAction: GotoSomeWhere) {
        onNextClickAction = onClickAction
        findViewById<AppCompatButton>(R.id.btn_right)?.let{
            it.text = "다음 페이지"
            it.setOnClickListener {
                actionNextEvent()
            }
            it.visibility= if(find) VISIBLE else GONE
        }
    }

    fun actionNextEvent() {
        if (pg != null && pg!!.visibility == View.VISIBLE && pg!!.size() > 0 && (pg!!.current() < pg!!.size() - 1) ) {
            pg!!.doNext()
            updateLastInfo(pg!!)
        }else {
            onNextClickAction?.let { it() }
        }
    }
    var onPrevClickAction: GotoSomeWhere? = null
    override fun showPrevBtn(find : Boolean, onClickAction: GotoSomeWhere) {
        onPrevClickAction = onClickAction
        findViewById<AppCompatButton>(R.id.btn_left)?.let{
            it.text = "이전 페이지"
            it.setOnClickListener {
                actionPrevEvent()
            }
            it.visibility= if(find) VISIBLE else GONE
        }
    }


    fun actionPrevEvent() {
        if (pg != null && pg!!.visibility == View.VISIBLE && pg!!.size() > 0 && pg!!.current() > 0 ) {
            pg!!.doPrev()
            updateLastInfo(pg!!)
        } else {
            onPrevClickAction?.let{ it() }
        }
    }

    override fun onBackPressed() {
        var layer = findViewById<PagedTextLayout>(R.id.paged_layer)

        if (!didBackPress) {
            firstBackPress()
            return
        }

        if (layer != null && layer.visibility == View.VISIBLE) {
            didBackPress = false
            layer.visibility = GONE
            onTouch(TouchArea.Center)
            return
        }

        if (mBaseWebContentsViewer.webview.canGoBack()) {
            mBaseWebContentsViewer.webview.goBack()
            return
        }

        if (!didBackPress) {
            firstBackPress()
            return
        }

        didBackPress = false

        super.onBackPressed()
    }


    override fun showAlert(alert: String) {
        Log.i(TAG,"showAlert >> " + alert)
    }

    override fun onLoadedContents(contents: String) {
        pg = null;
        findViewById<PagedTextLayout>(R.id.paged_layer).apply {
            if (contents != null) {
                pg = this
                visibility = VISIBLE
                mPagedTextViewInterface = this@Intro
                setText(contents.replace("\\n", System.getProperty("line.separator")))
                setTextSize(22f)
                if(lastInfo != null && lastInfo!!.pageUrl.equals(mBaseWebContentsViewer.webview.url)) {
                    this@Intro.findViewById<ProgressBar>(R.id.progress)?.visibility = VISIBLE
                    pg?.postDelayed({
                        next(lastInfo!!.pageIndex)
                        pg?.post {
                            this@Intro.findViewById<ProgressBar>(R.id.progress)?.visibility = GONE
                        }
                    },1000)
                }
                forceUpdateUI()
            }
        }

        Log.i(TAG,"onLoadedContents >> " + contents)
    }

    var currentTitle : String = ""
    var currentChapter : Int = 0

    override fun onFindTitle(contents: String) {
        findViewById<TextView>(R.id.textView).text = contents
        var testRegex = """[^0-9]""".toRegex();
        Blog.LOGI(TAG,"onFindTitle >> " + contents + "   :::  ${testRegex.replace(contents,"")}")
        if(contents.contains("-")) {
            currentTitle = contents.split("-")[0]
            currentChapter = testRegex.replace(contents.split("-")[1],"").toInt()
        }


    }

    override fun onStartLoad() {
        findViewById<ProgressBar>(R.id.progress).visibility = VISIBLE
    }

    override fun completePageLoad(lastInfo: LastInfo) {
        if(this.lastInfo == null || !(this.lastInfo?.pageUrl.equals(lastInfo?.pageUrl))) {
            saveLastInfo(lastInfo)
        }
        findViewById<ProgressBar>(R.id.progress).visibility = GONE
    }

    fun saveLastInfo(lastInfo: LastInfo) {
        val windowManager = getSystemService(WINDOW_SERVICE)
        val configuration: Configuration = getResources().getConfiguration()
        val config = RealmConfiguration.Builder(setOf(LastInfo::class))
            .schemaVersion(1)
            .build()
        val realm = Realm.open(config)
        realm.writeBlocking {
            lastInfo.displayOrientation = configuration.orientation
            copyToRealm(lastInfo)
        }
        Blog.LOGD(log ="Successfully opened realm: ${realm.configuration.name}")
        realm.close()
    }

    fun updateLastInfo(pagedTextLayout: PagedTextLayout) {
        val windowManager = getSystemService(WINDOW_SERVICE)
        val configuration: Configuration = getResources().getConfiguration()
        val config = RealmConfiguration.Builder(setOf(LastInfo::class))
            .schemaVersion(1)
            .build()
        val realm = Realm.open(config)

        realm.writeBlocking {
            var info = this.query<LastInfo>()?.find()?.last()
            info?.pageIndex = pagedTextLayout.current()
            info?.displayOrientation = configuration.orientation
        }

        Blog.LOGD(log ="Successfully opened realm: ${realm.configuration.name}")
        realm.close()
    }
    override fun onKeyClick(keyCode: Int): Boolean {
        when(keyCode) {
            KeyEvent.KEYCODE_VOLUME_DOWN ->{actionNextEvent()}
            KeyEvent.KEYCODE_VOLUME_UP ->{actionPrevEvent()}
            KeyEvent.KEYCODE_VOLUME_MUTE -> {actionNextEvent()}

        }
        return super.onKeyClick(keyCode)
    }

    override fun onTouch(touchArea: TouchArea) {
        Blog.LOGD(log="onTouch")
        when (touchArea) {
            TouchArea.Center-> {
                findViewById<View>(R.id.btn_right).visibility = VISIBLE
                findViewById<View>(R.id.btn_left).visibility = VISIBLE
                findViewById<View>(R.id.btn_setting).visibility = VISIBLE

                findViewById<View>(R.id.textView).visibility = VISIBLE
                findViewById<View>(R.id.btn_home).visibility = VISIBLE
                findViewById<View>(R.id.btn_list).visibility = VISIBLE
                findViewById<View>(R.id.btn_menu).visibility = VISIBLE
                findViewById<View>(R.id.btn_rotate).visibility = VISIBLE

            }
            TouchArea.Right -> {
                actionNextEvent()
            }
            TouchArea.Left-> {
                actionPrevEvent()
            }
            else -> {

            }
        }


    }

    override fun onSwipeLeft() {
        Blog.LOGD(log="onSwipeLeft")
        actionNextEvent()

    }

    override fun onSwipeRight() {
        Blog.LOGD(log="onSwipeRight")
        actionPrevEvent()
    }


    override fun onTimeoverTouch() {
        Blog.LOGD(log="onTimeoverTouch")
        findViewById<View>(R.id.btn_right).visibility = GONE
        findViewById<View>(R.id.btn_left).visibility = GONE
        findViewById<View>(R.id.btn_setting).visibility = GONE

        findViewById<View>(R.id.textView).visibility = GONE
        findViewById<View>(R.id.btn_home).visibility = GONE
        findViewById<View>(R.id.btn_list).visibility = GONE
        findViewById<View>(R.id.btn_menu).visibility = GONE
        findViewById<View>(R.id.btn_rotate).visibility = GONE

    }

    companion object {
        private const val TAG = "DualScreenStatus"
    }
}