package app.dudu.ime

import android.content.Intent
import android.inputmethodservice.InputMethodService
import android.view.KeyEvent
import android.view.View
import android.view.inputmethod.EditorInfo
import android.view.inputmethod.InputMethodManager
import androidx.compose.ui.platform.ComposeView
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.LifecycleRegistry
import androidx.lifecycle.ViewModelStore
import androidx.lifecycle.ViewModelStoreOwner
import androidx.lifecycle.setViewTreeLifecycleOwner
import androidx.lifecycle.setViewTreeViewModelStoreOwner
import androidx.savedstate.SavedStateRegistry
import androidx.savedstate.SavedStateRegistryController
import androidx.savedstate.SavedStateRegistryOwner
import androidx.savedstate.setViewTreeSavedStateRegistryOwner
import app.dudu.app.MainActivity
import app.dudu.design.DuduDesign
import app.dudu.ime.ui.KeyboardScreen
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.cancel

/**
 * dudu 输入法服务。
 *
 * 键盘视图选型：**Compose（ComposeView in onCreateInputView）**，理由——
 *  1. 键盘只有一屏自绘 UI（工具条 / 功能键行 / MicBar / partial 条），无传统键位矩阵，
 *     Compose 的状态驱动渲染 + 动画（波形）比手写 View 省一半代码且不易错；
 *  2. 主 App 同为 Compose，设计令牌（DuduTheme/DuduPalette）与组件直接复用；
 *  3. IME 场景下 Compose 的已知坑只有一个：ComposeView 依赖 ViewTree*Owner，
 *     InputMethodService 不是 LifecycleOwner——本类自行实现三个 Owner 并挂到
 *     decorView 上（windowRecomposer 从 rootView 向上查找），这是 FlorisBoard 等
 *     开源键盘验证过的稳定方案。
 */
class DuduImeService : InputMethodService(),
    LifecycleOwner, ViewModelStoreOwner, SavedStateRegistryOwner {

    // ─── Owner 实现（Compose in IME 的宿主桥） ───────────────────────────────
    private val lifecycleRegistry = LifecycleRegistry(this)
    override val lifecycle: Lifecycle get() = lifecycleRegistry

    private val store = ViewModelStore()
    override val viewModelStore: ViewModelStore get() = store

    private val savedStateController = SavedStateRegistryController.create(this)
    override val savedStateRegistry: SavedStateRegistry
        get() = savedStateController.savedStateRegistry

    private val scope = CoroutineScope(SupervisorJob() + Dispatchers.Main.immediate)
    private lateinit var controller: KeyboardController

    override fun onCreate() {
        super.onCreate()
        savedStateController.performRestore(null)
        lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE)

        controller = KeyboardController(
            context = this,
            scope = scope,
            commitText = { text -> currentInputConnection?.commitText(text, 1) },
            openMainApp = ::openMainApp,
        )
    }

    override fun onCreateInputView(): View {
        // windowRecomposer 从 rootView（decorView）向上查找 Owner，必须挂在 decorView
        window?.window?.decorView?.let { decor ->
            decor.setViewTreeLifecycleOwner(this)
            decor.setViewTreeViewModelStoreOwner(this)
            decor.setViewTreeSavedStateRegistryOwner(this)
        }
        lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START)

        return ComposeView(this).apply {
            setContent {
                DuduDesign {
                    KeyboardScreen(
                        controller = controller,
                        onSwitchIme = ::switchIme,
                        onText = { t -> currentInputConnection?.commitText(t, 1) },
                        onBackspace = { sendDownUpKeyEvents(KeyEvent.KEYCODE_DEL) },
                        onEnter = ::performEnter,
                        onOpenApp = { openMainApp("home") },
                    )
                }
            }
        }
    }

    override fun onStartInputView(editorInfo: EditorInfo?, restarting: Boolean) {
        super.onStartInputView(editorInfo, restarting)
        lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_RESUME)
        controller.clearNotice()
    }

    override fun onFinishInputView(finishingInput: Boolean) {
        // 键盘收起：终止进行中的会话（cancel），不上屏
        controller.abort()
        lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_PAUSE)
        super.onFinishInputView(finishingInput)
    }

    override fun onDestroy() {
        controller.abort()
        lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY)
        scope.cancel()
        super.onDestroy()
    }

    // ─── 功能键 ──────────────────────────────────────────────────────────────

    /** 发送 = 宿主 return key：优先 editor action，退回 KEYCODE_ENTER。 */
    private fun performEnter() {
        val ic = currentInputConnection ?: return
        val action = currentInputEditorInfo?.imeOptions?.and(EditorInfo.IME_MASK_ACTION)
        if (action != null && action != EditorInfo.IME_ACTION_NONE && action != EditorInfo.IME_ACTION_UNSPECIFIED) {
            ic.performEditorAction(action)
        } else {
            sendDownUpKeyEvents(KeyEvent.KEYCODE_ENTER)
        }
    }

    /** 切输入法：系统选择器（minSdk 26 下最通用的方式）。 */
    private fun switchIme() {
        val imm = getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager
        imm.showInputMethodPicker()
    }

    /** 从键盘打开主 App：登录 / 购买 / 授权引导。 */
    private fun openMainApp(dest: String) {
        startActivity(
            Intent(this, MainActivity::class.java)
                .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
                .putExtra(MainActivity.EXTRA_DEST, dest)
        )
    }
}
