package com.keyboard.journey

import android.graphics.BitmapFactory
import android.graphics.drawable.BitmapDrawable
import android.inputmethodservice.InputMethodService
import android.net.Uri
import android.view.View
import android.view.inputmethod.EditorInfo
import android.view.inputmethod.InputConnection
import android.widget.VideoView
import com.keyboard.journey.util.AppSharedPreferences
import com.keyboard.journey.util.colorsXmlPullParser
import com.keyboard.journey.util.currentlyThemeUFileString
import com.keyboard.journey.util.getBitmapDrawable
import com.keyboard.journey.util.getPath
import com.keyboard.journey.util.getRawVideoPath
import com.keyboard.journey.util.getStateDrawable
import com.keyboard.journey.view.JourneyKeyboardView
import com.keyboard.journey.view.Keyboard
import com.keyboard.journey.view.KeyboardView
import com.keyboard.journey.view.JourneyKeyboard
import java.io.File

class KeyboardService : InputMethodService() {

    private lateinit var keyboardView: JourneyKeyboardView
    private lateinit var currentKeyboard: Keyboard
    private var isAllCaps = false
    private var isCap = false
    private lateinit var rootView: View

    override fun onCreateInputView(): View {
        rootView = layoutInflater.inflate(R.layout.custom_keyboard, null) // 这里使用了一个容器布局
        keyboardView = rootView.findViewById(R.id.keyboardView) // 在容器布局中找到 KeyboardView 的引用
        currentKeyboard = Keyboard(this, R.xml.my_custom_keyboard_layout)
        keyboardView.keyboard = currentKeyboard
        keyboardView.setOnKeyboardActionListener(onKeyboardActionListener)

        isCap = keyboardView.isCap()
        isAllCaps = keyboardView.isAllCaps()

        return rootView // 返回包含 KeyboardView 的容器布局
    }

    override fun onWindowShown() {
        super.onWindowShown()
        updateConfig()
    }

    private fun updateConfig() {
        val currentlyUrl = AppSharedPreferences(this).getCurrentlyThemeUrl()
        if (currentlyUrl.isNotEmpty()) {
            val currentlyThemeUFile = currentlyThemeUFileString(this, currentlyUrl)
            val config = JourneyKeyboardView.Config(this)
            config.keyBackground = getStateDrawable(this,
                getPath(currentlyThemeUFile, "btn_keyboard_key_normal_normal.9.png"),
                getPath(currentlyThemeUFile, "btn_keyboard_key_normal_pressed.9.png")
            )
            config.specialKeyBackground = getStateDrawable(this,
                getPath(currentlyThemeUFile, "btn_keyboard_spacekey_normal_normal.9.png"),
                getPath(currentlyThemeUFile, "btn_keyboard_spacekey_normal_pressed.9.png")
            )
            config.deleteDrawable = getStateDrawable(this,
                getPath(currentlyThemeUFile, "sym_keyboard_delete_normal.png"),
                getPath(currentlyThemeUFile, "sym_keyboard_delete_pressed.png")
            )
            config.toggleKeyBackground = getStateDrawable(this,
                getPath(currentlyThemeUFile, "btn_keyboard_key_toggle_normal_on.9.png"),
                getPath(currentlyThemeUFile, "btn_keyboard_key_toggle_pressed_on.9.png")
            )

            val colorMap = colorsXmlPullParser(currentlyThemeUFile)
            colorMap.forEach { (name, value) ->
                if (name == "key_text_color_normal") {
                    config.keyTextColor = value
                    config.keySpecialTextColor = value
                }
                if (name == "key_text_color_functional") {
                    config.toggleKeyTextColor = value
                }
            }
            config.capitalDrawable =
                getBitmapDrawable(this,currentlyThemeUFile, "sym_keyboard_shift_locked.png")
            config.lowerDrawable = getBitmapDrawable(this,currentlyThemeUFile, "sym_keyboard_shift.png")
            config.capitalLockDrawable =
                getBitmapDrawable(this,currentlyThemeUFile, "sym_keyboard_shift_locked.png")

            val videoView = rootView.findViewById<VideoView>(R.id.videoView)
            val videoPath = getRawVideoPath(currentlyThemeUFile)
            if (File(videoPath).exists()) {
                // 设置视频路径并启动播放
                videoView.setVideoURI(Uri.parse(videoPath))
                videoView.setOnPreparedListener { mp ->
                    mp.isLooping = true // 循环播放
                    videoView.start()
                }
                videoView.visibility = View.VISIBLE
            } else {
                val imagePath =
                    "$currentlyThemeUFile/res/drawable-xxhdpi-v4/keyboard_background.jpg"
                val bitmap = BitmapFactory.decodeFile(imagePath)
                val background = BitmapDrawable(resources, bitmap)
                rootView.background = background
                videoView.visibility = View.GONE
            }
            keyboardView.setConfig(config)
        }
    }
    
    private val onKeyboardActionListener = object : KeyboardView.OnKeyboardActionListener {
        override fun onKey(primaryCode: Int, keyCodes: IntArray?) {
            val ic = currentInputConnection
            performKey(ic, primaryCode, keyCodes)
        }

        override fun onPress(primaryCode: Int) {}

        override fun onRelease(primaryCode: Int) {}

        override fun onText(text: CharSequence?) {}

        override fun swipeLeft() {}

        override fun swipeRight() {}

        override fun swipeDown() {}

        override fun swipeUp() {}
    }

    private var keyboardType = KeyboardType.NORMAL

    private val keyboardNormal by lazy { Keyboard(this, R.xml.my_custom_keyboard_layout) }
    private val keyboardNormalModeChange by lazy { Keyboard(this, R.xml.keyboard_mode_change) }
    private val keyboardNormalMore by lazy { Keyboard(this, R.xml.keyboard_more_symbol) }

    /**
     * 根据 primaryCode去做相应的处理
     */
    private fun performKey(ic: InputConnection, primaryCode: Int, keyCodes: IntArray?) {
        when (primaryCode) {
            JourneyKeyboard.KEYCODE_SHIFT -> keyShift()
            JourneyKeyboard.KEYCODE_MODE_CHANGE -> keyModeChange()
            JourneyKeyboard.KEYCODE_CANCEL -> keyCancel(primaryCode)
            JourneyKeyboard.KEYCODE_DONE -> keyDone(primaryCode)
            JourneyKeyboard.KEYCODE_DELETE -> keyDelete(ic)
            JourneyKeyboard.KEYCODE_MODE_BACK -> keyBack(false)
            JourneyKeyboard.KEYCODE_BACK -> keyBack(true)
            JourneyKeyboard.KEYCODE_MORE -> keyMore()
            //无效的按键值，打印相关日志
            else -> commitText(ic, primaryCode)
        }
    }

    private fun commitText(ic: InputConnection, primaryCode: Int) {
        val code = primaryCode.toChar().toString()
        ic.commitText(code, 1)

        if (isCap && !isAllCaps) {//如果当前是大写键盘，并且并且没有锁定，则自动变换成小写键盘
            isCap = false
            isAllCaps = false
            toLowerCaseKey(currentKeyboard)

            keyboardView.run {
                setCap(isCap)
                setAllCaps(isAllCaps)
                keyboard = currentKeyboard
            }
        }
    }
    /**
     * 触发删除
     */
    private fun keyDelete(ic: InputConnection) {
        ic.deleteSurroundingText(1, 0)
    }

    /**
     * 触发Shift，切换大小字母键盘
     */
    private fun keyShift() {
        //将键盘进行大小写键盘切换
        if (isAllCaps) {//上次状态为大写锁定时，转换为小写
            toLowerCaseKey(currentKeyboard)
        } else {//反之上次状态即为小写时，转换为大写
            toUpperCaseKey(currentKeyboard)
        }

        when {
            isAllCaps -> {//上次状态为锁定时，此次状态将改变为小写，将变量状态改变
                isAllCaps = false
                isCap = false
            }

            isCap -> {//上次状态为非锁定，此次状态改变为锁定
                isAllCaps = true
            }

            else -> {//上次状态为小写（默认）,此次状态改变为大写
                isCap = true
                isAllCaps = false
            }
        }

        keyboardView.let {
            it.setCap(isCap)
            it.setAllCaps(isAllCaps)
            it.keyboard = currentKeyboard
        }


    }

    /**
     * 转换为大写
     */
    private fun toUpperCaseKey(keyboard: Keyboard) {
        keyboard.run {
            for (key in keys) {
                if (key.label?.length == 1) {// 一个字符
                    var c = key.label.toString()[0]
                    if (c.isLowerCase()) { //是小写字母
                        //转换为大写
                        val letter = c.toUpperCase()
                        key.label = letter.toString()
                        key.codes[0] = letter.toInt()
                    }

                }
            }
        }

    }

    /**
     * 转换为小写
     */
    private fun toLowerCaseKey(keyboard: Keyboard) {
        keyboard.run {
            for (key in keys) {
                if (key.label?.length == 1) {// 一个字符
                    var c = key.label.toString()[0]
                    if (c.isUpperCase()) { //是大写字母
                        //转换为小写
                        val letter = c.toLowerCase()
                        key.label = letter.toString()
                        key.codes[0] = letter.toInt()
                    }

                }
            }
        }

    }

    /**
     * 模式改变，切换键盘
     */
    private fun keyModeChange() {
        when (keyboardType) {
            JourneyKeyboard.KeyboardType.NORMAL -> {
                keyboardType = KeyboardType.NORMAL_MODE_CHANGE
            }
        }

        switchKeyboard()
    }

    private fun switchKeyboard() {
        when (keyboardType) {
            KeyboardType.NORMAL -> {
                currentKeyboard = keyboardNormal
            }

            KeyboardType.NORMAL_MODE_CHANGE -> {
                currentKeyboard = keyboardNormalModeChange
            }

            KeyboardType.NORMAL_MORE -> {
                currentKeyboard = keyboardNormalMore
            }
        }

        keyboardView.run {
            keyboard = currentKeyboard
        }

    }

    /**
     * 取消，关闭键盘
     */
    private fun keyCancel(primaryCode: Int) {
        val ic = currentInputConnection
        ic?.performEditorAction(EditorInfo.IME_ACTION_DONE)
    }

    /**
     * 完成
     */
    private fun keyDone(primaryCode: Int) {
        val ic = currentInputConnection
        ic?.performEditorAction(EditorInfo.IME_ACTION_DONE)
    }


    /**
     * 返回
     */
    private fun keyBack(isBack: Boolean) {
        when (keyboardType) {
            KeyboardType.NORMAL_MODE_CHANGE -> {
                keyboardType = KeyboardType.NORMAL
            }

            KeyboardType.NORMAL_MORE -> {
                keyboardType = if (isBack) KeyboardType.NORMAL else KeyboardType.NORMAL_MODE_CHANGE
            }
        }

        switchKeyboard()
    }

    /**
     * 更多
     */
    private fun keyMore() {
        when (keyboardType) {
            KeyboardType.NORMAL -> {
                keyboardType = KeyboardType.NORMAL_MORE
            }

            KeyboardType.NORMAL_MODE_CHANGE -> {
                keyboardType = KeyboardType.NORMAL_MORE
            }
        }

        switchKeyboard()
    }


    object KeyboardType {
        /**
         * 默认键盘 - 字母带符号
         */
        const val NORMAL = 0x00000001

        /**
         * 默认键盘 - 切换键盘
         */
        internal const val NORMAL_MODE_CHANGE = 0x00000002

        /**
         * 默认键盘 - 更多
         */
        internal const val NORMAL_MORE = 0x00000003
    }

}