package com.example.myapplication.keyboard

import android.content.Context
import android.graphics.Bitmap
import android.graphics.Color
import android.graphics.drawable.BitmapDrawable
import android.graphics.drawable.Drawable
import android.graphics.drawable.GradientDrawable
import android.os.Build
import android.os.VibrationEffect
import android.os.Vibrator
import android.util.TypedValue
import android.view.Gravity
import android.view.MotionEvent
import android.view.View
import android.widget.PopupWindow
import android.widget.TextView
import com.example.myapplication.theme.ThemeManager

class MainKeyboard(
    env: KeyboardEnvironment,
    private val swipeAltMap: Map<Char, Char>,
    /**
     * 交给 MyInputMethodService 切换 Shift 状态，并返回最新状态
     */
    private val onToggleShift: () -> Boolean
) : BaseKeyboard(env) {

    override val rootView: View = env.layoutInflater.inflate(
        env.ctx.resources.getIdentifier("keyboard", "layout", env.ctx.packageName),
        null
    )

    private var isShiftOn: Boolean = false
    private var keyPreviewPopup: PopupWindow? = null

    // ======================== 震动相关 ========================

    private val vibrator: Vibrator? =
        env.ctx.getSystemService(Context.VIBRATOR_SERVICE) as? Vibrator

        private fun vibrateKey(
            duration: Long = 20L,     // 时间：10~40 推荐
            amplitude: Int = 150      // 1~255，100~150 最舒服
        ) {
            val v = vibrator ?: return
            if (!v.hasVibrator()) return
        
            try {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                    v.vibrate(
                        VibrationEffect.createOneShot(duration, amplitude)
                    )
                } else {
                    @Suppress("DEPRECATION")
                    v.vibrate(duration)
                }
            } catch (_: SecurityException) {
                // 没权限就自动静音，不崩溃
            }
        }

    init {
        applyPerKeyBackgroundForMainKeyboard(rootView)

        applyTheme(
            env.currentTextColor,
            env.currentBorderColor,
            env.currentBackgroundColor
        )

        setupListenersForMain(rootView)
    }

    // ======================== 背景图 ========================

    private fun applyPerKeyBackgroundForMainKeyboard(root: View) {
        // a..z 小写
        var c = 'a'
        while (c <= 'z') {
            val idName = "key_$c"
            applyKeyBackground(root, idName)
            c++
        }

        // 键盘背景
        applyKeyBackground(root, "background")

        // 其他功能键
        val others = listOf(
            "key_space",
            "key_send",
            "key_del",
            "key_up",
            "key_123",
            "key_ai"
        )
        for (idName in others) {
            applyKeyBackground(root, idName)
        }
    }

    private fun applyKeyBackground(
        root: View,
        viewIdName: String,
        drawableName: String? = null
    ) {
        val res = env.ctx.resources
        val viewId = res.getIdentifier(viewIdName, "id", env.ctx.packageName)
        if (viewId == 0) return
        val v = root.findViewById<View?>(viewId) ?: return

        val keyName = drawableName ?: viewIdName
        val rawDrawable = ThemeManager.getDrawableForKey(env.ctx, keyName) ?: return

        if (viewIdName == "background") {
            val scaled = scaleDrawableToHeight(rawDrawable, 243f)
            v.background = scaled
            return
        }
        v.background = rawDrawable
    }

    private fun scaleDrawableToHeight(src: Drawable, targetDp: Float): Drawable {
        val res = env.ctx.resources
        val dm = res.displayMetrics
        val targetHeightPx = TypedValue.applyDimension(
            TypedValue.COMPLEX_UNIT_DIP,
            targetDp,
            dm
        ).toInt()

        val bitmap = (src as? BitmapDrawable)?.bitmap ?: return src
        val w = bitmap.width
        val h = bitmap.height

        val ratio = targetHeightPx.toFloat() / h
        val targetWidthPx = (w * ratio).toInt()

        val scaled = Bitmap.createScaledBitmap(bitmap, targetWidthPx, targetHeightPx, true)
        return BitmapDrawable(res, scaled).apply {
            setBounds(0, 0, targetWidthPx, targetHeightPx)
        }
    }

    // ======================== 事件绑定 ========================

    private fun setupListenersForMain(view: View) {
        val res = env.ctx.resources
        val pkg = env.ctx.packageName

        // a..z：支持上滑副字符
        var c = 'a'
        while (c <= 'z') {
            val id = res.getIdentifier("key_$c", "id", pkg)
            val tv = view.findViewById<TextView?>(id)
            if (tv != null) {
                val baseChar = c
                val altChar = swipeAltMap[baseChar]

                attachKeyTouchWithSwipe(
                    tv,
                    normalCharProvider = { baseChar },
                    altCharProvider = altChar?.let { ac ->
                        { ac }
                    }
                )
            }
            c++
        }

        // space
        view.findViewById<View?>(res.getIdentifier("key_space", "id", pkg))
            ?.setOnClickListener {
                vibrateKey()
                env.commitKey(' ')
            }

        // Shift
        val shiftId = res.getIdentifier("key_up", "id", pkg)
        view.findViewById<View?>(shiftId)?.setOnClickListener {
            vibrateKey()
            isShiftOn = onToggleShift()
            it.isActivated = isShiftOn
            updateKeyBackgroundsForLetters(view)
        }

        // 删除（单击；长按由 MyInputMethodService 挂）
        view.findViewById<View?>(res.getIdentifier("key_del", "id", pkg))
            ?.setOnClickListener {
                vibrateKey()
                env.deleteOne()
            }

        // 切换数字键盘
        view.findViewById<View?>(res.getIdentifier("key_123", "id", pkg))
            ?.setOnClickListener {
                vibrateKey()
                env.showNumberKeyboard()
            }

        // 跳 AI
        view.findViewById<View?>(res.getIdentifier("key_ai", "id", pkg))
            ?.setOnClickListener {
                vibrateKey()
                env.showAiKeyboard()
            }

        // 发送
        view.findViewById<View?>(res.getIdentifier("key_send", "id", pkg))
            ?.setOnClickListener {
                vibrateKey()
                env.performSendAction()
            }
    }

    // Shift 后更新字母按键背景（key_a vs key_a_up）
    private fun updateKeyBackgroundsForLetters(root: View) {
        var c = 'a'
        while (c <= 'z') {
            val idName = "key_$c"
            val drawableName = if (isShiftOn) "${idName}_up" else idName
            applyKeyBackground(root, idName, drawableName)
            c++
        }

        val upKeyIdName = "key_up"
        val upDrawableName = if (isShiftOn) "key_up_upper" else "key_up"
        applyKeyBackground(root, upKeyIdName, upDrawableName)
    }

    // ======================== 触摸 + 预览 ========================

    private fun attachKeyTouchWithSwipe(
        view: View,
        normalCharProvider: () -> Char,
        altCharProvider: (() -> Char)?
    ) {
        val swipeThreshold = 20.dpToPx().toFloat()
        var downY = 0f
        var isAlt = false
        var currentChar: Char = '\u0000'

        view.setOnTouchListener { v, event ->
            when (event.actionMasked) {
                MotionEvent.ACTION_DOWN -> {
                    downY = event.rawY
                    isAlt = false
                    currentChar = normalCharProvider()
                    vibrateKey()   // 按下就震
                    showKeyPreview(v, currentChar.toString())
                    v.isPressed = true
                    true
                }
                MotionEvent.ACTION_MOVE -> {
                    if (altCharProvider != null) {
                        val dy = event.rawY - downY
                        val shouldAlt = dy < -swipeThreshold
                        if (shouldAlt != isAlt) {
                            isAlt = shouldAlt
                            currentChar = if (isAlt) altCharProvider() else normalCharProvider()
                            showKeyPreview(v, currentChar.toString())
                        }
                    }
                    true
                }
                MotionEvent.ACTION_UP -> {
                    env.commitKey(currentChar)
                    keyPreviewPopup?.dismiss()
                    v.isPressed = false
                    true
                }
                MotionEvent.ACTION_CANCEL,
                MotionEvent.ACTION_OUTSIDE -> {
                    keyPreviewPopup?.dismiss()
                    v.isPressed = false
                    true
                }
                else -> false
            }
        }
    }

    private fun showKeyPreview(anchor: View, text: String) {
        keyPreviewPopup?.dismiss()

        val tv = TextView(env.ctx).apply {
            this.text = text
            textSize = 26f
            setTextColor(Color.BLACK)
            setPadding(20, 10, 20, 10)
            background = GradientDrawable().apply {
                shape = GradientDrawable.RECTANGLE
                cornerRadius = 16f
                setColor(Color.WHITE)
                setStroke(1, Color.parseColor("#33000000"))
            }
            gravity = Gravity.CENTER
        }

        val w = (anchor.width * 1.2f).toInt()
        val h = (anchor.height * 1.2f).toInt()

        keyPreviewPopup = PopupWindow(tv, w, h, false).apply {
            isClippingEnabled = false
        }

        keyPreviewPopup?.showAsDropDown(
            anchor,
            -(w - anchor.width) / 2,
            -(h + anchor.height * 1.1f).toInt()
        )
    }
}
