package com.example.myapplication.keyboard

import android.content.Intent
import android.content.res.ColorStateList
import android.graphics.Bitmap
import android.graphics.drawable.BitmapDrawable
import android.graphics.drawable.Drawable
import android.util.TypedValue
import android.view.Gravity
import android.view.View
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.TextView
import com.example.myapplication.MainActivity
import com.example.myapplication.theme.ThemeManager
import android.os.Handler
import android.os.Looper
import android.widget.ScrollView
import com.example.myapplication.network.NetworkClient
import com.example.myapplication.network.LlmStreamCallback
import okhttp3.Call

class AiKeyboard(
    env: KeyboardEnvironment
) : BaseKeyboard(env) {

    private var currentStreamCall: Call? = null
    private val mainHandler = Handler(Looper.getMainLooper())

    private val messagesContainer: LinearLayout by lazy {
        val res = env.ctx.resources
        val id = res.getIdentifier("container_messages", "id", env.ctx.packageName)
        rootView.findViewById(id)
    }

    private val messagesScrollView: ScrollView by lazy {
        val res = env.ctx.resources
        val id = res.getIdentifier("scroll_messages", "id", env.ctx.packageName)
        rootView.findViewById(id)
    }

    // 当前正在流式更新的那一个 AI 文本
    private var currentAssistantTextView: TextView? = null

    // 用来处理 <SPLIT> 的缓冲
    private val streamBuffer = StringBuilder()


     //新建一条 AI 消息（空内容），返回里面的 TextView 用来后续流式更新
     
    private fun addAssistantMessage(initialText: String = ""): TextView {
        val inflater = env.layoutInflater
        val res = env.ctx.resources
        val layoutId = res.getIdentifier("item_ai_message", "layout", env.ctx.packageName)

        val itemView = inflater.inflate(layoutId, messagesContainer, false) as LinearLayout
        val tv = itemView.findViewById<TextView>(
            res.getIdentifier("tv_content", "id", env.ctx.packageName)
        )
        tv.text = initialText
        messagesContainer.addView(itemView)

        scrollToBottom()
        return tv
    }

    /**
     * （可选）如果你也想显示用户提问
     */
    private fun addUserMessage(text: String) {
        // 简单写：复用同一个 item 布局
        val tv = addAssistantMessage(text)
        // 这里可以改成设置 gravity、背景区分用户/AI 等
    }

    private fun scrollToBottom() {
        // 延迟一点点执行，保证 addView 完成后再滚动
        messagesScrollView.post {
            messagesScrollView.fullScroll(View.FOCUS_DOWN)
        }
    }

    //后端每来一个 llm_chunk 的 data，就调用一次这个方法
    private fun onLlmChunk(data: String) {
        // 丢掉 data=":\n\n" 这条
        if (data == ":\n\n") return

        // 确保在主线程更新 UI
        mainHandler.post {
            // 如果还没有正在流式的 TextView，就新建一条 AI 消息
            if (currentAssistantTextView == null) {
                currentAssistantTextView = addAssistantMessage("")
                streamBuffer.clear()
            }

            // 累积到缓冲区
            streamBuffer.append(data)

            // 先整体把 ":\n\n" 删掉（以防万一有别的地方混进来）
            var text = streamBuffer.toString().replace(":\n\n", "")

            // 处理 <SPLIT>：代表下一句/下一条消息
            val splitTag = "<SPLIT>"
            var index = text.indexOf(splitTag)

            while (index != -1) {
                // split 前面这一段是上一条消息的最终内容
                val before = text.substring(0, index)
                currentAssistantTextView?.text = before
                scrollToBottom()

                // 开启下一条 AI 消息
                currentAssistantTextView = addAssistantMessage("")

                // 剩下的留给下一轮
                text = text.substring(index + splitTag.length)
                index = text.indexOf(splitTag)
            }

            // 循环结束后 text 就是「当前这条消息的未完成尾巴」
            currentAssistantTextView?.text = text
            scrollToBottom()

            // 缓冲区只保留尾巴（避免无限变长）
            streamBuffer.clear()
            streamBuffer.append(text)
        }
    }

 
     // 收到 type="done" 时调用，表示这一轮回答结束
    private fun onLlmDone() {
        mainHandler.post {
            // 这里目前不需要做太多事，必要的话可以清掉 buffer
            streamBuffer.clear()
            currentAssistantTextView = null
        }
    }

    
     // 开始一次新的 AI 回答流式请求
     fun startAiStream(userQuestion: String) {
        // 可选：先把用户问题显示出来
        addUserMessage(userQuestion)

        // 如果之前有没结束的流，先取消
        currentStreamCall?.cancel()

        currentStreamCall = NetworkClient.startLlmStream(
            question = userQuestion,
            callback = object : LlmStreamCallback {
                override fun onEvent(type: String, data: String?) {
                    when (type) {
                        "llm_chunk" -> {
                            if (data != null) {
                                onLlmChunk(data)   // 这里就是之前写的流式 UI 更新
                            }
                        }
                        "done" -> {
                            onLlmDone()           // 一轮结束
                        }
                        "search_result" -> {
                        }
                    }
                }

                override fun onError(t: Throwable) {
                    addAssistantMessage("出错了：${t.message}")
                }
            }
        )
    }

    // 比如键盘关闭时可以调用一次，避免内存泄漏 / 多余请求
    fun cancelAiStream() {
        currentStreamCall?.cancel()
        currentStreamCall = null
    }



    // 以下是 BaseKeyboard 的实现
    override val rootView: View = run {
        val res = env.ctx.resources
        val layoutId = res.getIdentifier("ai_keyboard", "layout", env.ctx.packageName)
        if (layoutId != 0) {
            env.layoutInflater.inflate(layoutId, null) as View
        } else {
            // 如果找不到布局，创建一个默认的View
            LinearLayout(env.ctx).apply {
                orientation = LinearLayout.VERTICAL
                gravity = Gravity.CENTER
                addView(TextView(env.ctx).apply {
                    text = "AI Keyboard"
                })
            }
        }
    }

    init {
        applyKeyBackground(rootView, "background")
        applyTheme(
            env.currentTextColor,
            env.currentBorderColor,
            env.currentBackgroundColor
        )
        setupListeners()
    }
    
    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 setupListeners() {
        val res = env.ctx.resources
        val pkg = env.ctx.packageName

        // 获取ai_persona和ai_output视图引用
        val aiPersonaId = res.getIdentifier("ai_persona", "id", pkg)
        val aiOutputId = res.getIdentifier("ai_output", "id", pkg)
        
        val aiPersonaView = if (aiPersonaId != 0) rootView.findViewById<View?>(aiPersonaId) else null
        val aiOutputView = if (aiOutputId != 0) rootView.findViewById<View?>(aiOutputId) else null

        // 初始化显示状态：显示ai_persona，隐藏ai_output
        aiPersonaView?.visibility = View.VISIBLE
        aiOutputView?.visibility = View.GONE

        // 如果 ai_keyboard.xml 里有 “返回主键盘” 的按钮，比如 key_abc，就绑定一下
        val backId = res.getIdentifier("key_abc", "id", pkg)
        if (backId != 0) {
            rootView.findViewById<ImageView?>(backId)?.setOnClickListener {
                env.showMainKeyboard()
            }
        }

        // 绑定 VIP 按钮点击事件，跳转到充值页面
        val vipButtonId = res.getIdentifier("key_vip", "id", pkg)
        if (vipButtonId != 0) {
            rootView.findViewById<ImageView?>(vipButtonId)?.setOnClickListener {
                navigateToRechargeFragment()
            }
        }

        //显示切换
        val returnButtonId = res.getIdentifier("Return_keyboard", "id", pkg)
        if (returnButtonId != 0) {
            rootView.findViewById<View?>(returnButtonId)?.let { returnButton ->
                // 确保按钮可点击且可获得焦点，防止事件穿透
                returnButton.isClickable = true
                returnButton.isFocusable = true
                returnButton.setOnClickListener {
                    // 点击Return_keyboard：先隐藏ai_output，再显示ai_persona（顺序动画）
                    aiOutputView?.animate()?.alpha(0f)?.setDuration(150)?.withEndAction {
                        aiOutputView?.visibility = View.GONE
                        // 等ai_output完全隐藏后再显示ai_persona
                        aiPersonaView?.visibility = View.VISIBLE
                        aiPersonaView?.alpha = 0f
                        aiPersonaView?.animate()?.alpha(1f)?.setDuration(150)
                    }
                }
            }
        }

        val cardButtonId = res.getIdentifier("card", "id", pkg)
        if (cardButtonId != 0) {
            rootView.findViewById<View?>(cardButtonId)?.setOnClickListener {
                // 点击card：先隐藏ai_persona，再显示ai_output（顺序动画）
                aiPersonaView?.animate()?.alpha(0f)?.setDuration(150)?.withEndAction {
                    aiPersonaView?.visibility = View.GONE
                    // 等ai_persona完全隐藏后再显示ai_output
                    aiOutputView?.visibility = View.VISIBLE
                    aiOutputView?.alpha = 0f
                    aiOutputView?.animate()?.alpha(1f)?.setDuration(150)
                }
            }
        }


        


            // // 假设 ai_keyboard.xml 里有一个发送按钮 key_send
            // val sendId = res.getIdentifier("key_send", "id", pkg)
            // val inputId = res.getIdentifier("et_prompt", "id", pkg)   // 假设这是你的输入框 id
            
            // if (sendId != 0 && inputId != 0) {
            //     val inputView = rootView.findViewById<TextView?>(inputId)
            
            //     rootView.findViewById<View?>(sendId)?.setOnClickListener {
            //         val question = inputView?.text?.toString()?.trim().orEmpty()
            //         if (question.isNotEmpty()) {
            //             startAiStream(question)
            //         }
            //     }
            // }
    }

    private fun navigateToRechargeFragment() {
        try {
            val intent = Intent(env.ctx, MainActivity::class.java).apply {
                addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP)
                putExtra("navigate_to", "recharge_fragment")
            }
            env.ctx.startActivity(intent)
        } catch (e: Exception) {
            // 如果启动失败，记录错误日志
            android.util.Log.e("AiKeyboard", "Failed to navigate to recharge fragment", e)
        }
    }

    override fun applyTheme(
        textColor: ColorStateList,
        borderColor: ColorStateList,
        backgroundColor: ColorStateList
    ) {
        applyKeyBackgroundsForTheme()
    }
    // ==============================刷新主题==================================
    override fun applyKeyBackgroundsForTheme() {
        // 背景
        applyKeyBackground(rootView, "background")
    
        // // AI 键盘上的功能键（按你现有 layout 里出现过的 id 来列）
        // val others = listOf(
        //     "key_abc",          // 返回主键盘
        //     "key_vip",          // VIP
        //     "Return_keyboard",  // 返回 persona 页
        //     "card"              // 切换到 output 页
        //     // 如果后续 ai_keyboard.xml 里还有其它需要换肤的 key id，继续往这里加
        // )
        // others.forEach { applyKeyBackground(rootView, it) }
    }
}