package com.hikoncont.manager

import android.accessibilityservice.AccessibilityService
import android.content.ClipData
import android.content.ClipboardManager
import android.content.Context
import android.os.Bundle
import android.util.Log
import android.view.accessibility.AccessibilityNodeInfo
import com.hikoncont.service.AccessibilityRemoteService

/**
 * 输入控制器
 * 
 * 负责处理文本输入和系统按键操作
 */
class InputController(private val service: AccessibilityRemoteService) {
    
    companion object {
        private const val TAG = "InputController"
    }
    
    private val context: Context = service
    private val clipboardManager = context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
    
    /**
     * 输入文本 - 智能输入策略
     */
    fun inputText(text: String) {
        try {
            Log.d(TAG, "开始输入文本: $text")
            
            // ✅ vivo设备特殊处理：尝试键盘点击输入
            if (isVivoDevice() && shouldUseKeyboardClick(text)) {
                Log.d(TAG, "📱 vivo设备尝试键盘点击输入")
                if (tryKeyboardClickInput(text)) {
                    Log.d(TAG, "✅ vivo键盘点击输入成功")
                    return
                }
                Log.w(TAG, "⚠️ vivo键盘点击失败，回退到标准输入")
            }
            
            when {
                // 优先尝试直接设置文本
                tryDirectTextSetting(text) -> {
                    Log.d(TAG, "使用直接设置方式输入成功")
                }
                
                // 降级到剪贴板粘贴
                tryClipboardPaste(text) -> {
                    Log.d(TAG, "使用剪贴板粘贴方式输入成功")
                }
                
                // 最后使用逐字符模拟输入
                else -> {
                    simulateTyping(text)
                    Log.d(TAG, "使用模拟输入方式")
                }
            }
            
        } catch (e: Exception) {
            Log.e(TAG, "输入文本失败: $text", e)
        }
    }

    /**
     * ✅ 新增：追加字符到输入框 - 用于逐字符输入
     */
    fun appendCharacter(char: String) {
        try {
            Log.d(TAG, "追加字符: '$char'")
            
            when {
                // 优先尝试追加字符到现有文本
                tryAppendCharacter(char) -> {
                    Log.d(TAG, "使用追加方式输入字符成功: '$char'")
                }
                
                // 降级到剪贴板追加
                tryClipboardAppend(char) -> {
                    Log.d(TAG, "使用剪贴板追加方式输入字符成功: '$char'")
                }
                
                // 最后使用光标位置插入
                else -> {
                    tryCursorInsert(char)
                    Log.d(TAG, "使用光标插入方式输入字符: '$char'")
                }
            }
            
        } catch (e: Exception) {
            Log.e(TAG, "追加字符失败: '$char'", e)
        }
    }
    
    /**
     * 尝试直接设置文本
     */
    private fun tryDirectTextSetting(text: String): Boolean {
        return try {
            val focusedNode = findFocusedInputNode()
            focusedNode?.let { node ->
                val bundle = Bundle().apply {
                    putCharSequence(AccessibilityNodeInfo.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE, text)
                }
                val result = node.performAction(AccessibilityNodeInfo.ACTION_SET_TEXT, bundle)
                node.recycle()
                result
            } ?: false
        } catch (e: Exception) {
            Log.w(TAG, "直接设置文本失败", e)
            false
        }
    }
    
    /**
     * 尝试剪贴板粘贴
     */
    private fun tryClipboardPaste(text: String): Boolean {
        return try {
            // 1. 将文本复制到剪贴板
            val clipData = ClipData.newPlainText("remote_input", text)
            clipboardManager.setPrimaryClip(clipData)
            
            // 2. 模拟粘贴操作
            val focusedNode = findFocusedInputNode()
            focusedNode?.let { node ->
                val result = node.performAction(AccessibilityNodeInfo.ACTION_PASTE)
                node.recycle()
                result
            } ?: false
            
        } catch (e: Exception) {
            Log.w(TAG, "剪贴板粘贴失败", e)
            false
        }
    }
    
    /**
     * 模拟逐字符输入
     */
    private fun simulateTyping(text: String) {
        val focusedNode = findFocusedInputNode()
        focusedNode?.let { node ->
            try {
                // 设置新文本
                val bundle = Bundle().apply {
                    putCharSequence(AccessibilityNodeInfo.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE, text)
                }
                node.performAction(AccessibilityNodeInfo.ACTION_SET_TEXT, bundle)
                
            } catch (e: Exception) {
                Log.w(TAG, "模拟输入失败", e)
            } finally {
                node.recycle()
            }
        }
    }

    /**
     * ✅ 新增：尝试追加字符到现有文本
     */
    private fun tryAppendCharacter(char: String): Boolean {
        return try {
            val focusedNode = findFocusedInputNode()
            focusedNode?.let { node ->
                // 获取当前文本
                val currentText = node.text?.toString() ?: ""
                // 追加新字符
                val newText = currentText + char
                
                val bundle = Bundle().apply {
                    putCharSequence(AccessibilityNodeInfo.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE, newText)
                }
                val result = node.performAction(AccessibilityNodeInfo.ACTION_SET_TEXT, bundle)
                node.recycle()
                result
            } ?: false
        } catch (e: Exception) {
            Log.w(TAG, "追加字符失败", e)
            false
        }
    }

    /**
     * ✅ 新增：尝试使用剪贴板追加字符
     */
    private fun tryClipboardAppend(char: String): Boolean {
        return try {
            val focusedNode = findFocusedInputNode()
            focusedNode?.let { node ->
                // 获取当前文本
                val currentText = node.text?.toString() ?: ""
                // 追加新字符
                val newText = currentText + char
                
                // 将新文本复制到剪贴板
                val clipData = ClipData.newPlainText("remote_append", newText)
                clipboardManager.setPrimaryClip(clipData)
                
                // 先清空再粘贴
                val clearBundle = Bundle().apply {
                    putCharSequence(AccessibilityNodeInfo.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE, "")
                }
                node.performAction(AccessibilityNodeInfo.ACTION_SET_TEXT, clearBundle)
                
                // 粘贴新内容
                val result = node.performAction(AccessibilityNodeInfo.ACTION_PASTE)
                node.recycle()
                result
            } ?: false
            
        } catch (e: Exception) {
            Log.w(TAG, "剪贴板追加失败", e)
            false
        }
    }

    /**
     * ✅ 新增：尝试在光标位置插入字符
     */
    private fun tryCursorInsert(char: String) {
        val focusedNode = findFocusedInputNode()
        focusedNode?.let { node ->
            try {
                // 获取当前文本和光标位置
                val currentText = node.text?.toString() ?: ""
                
                // 如果无法获取光标位置，默认追加到末尾
                val newText = currentText + char
                
                val bundle = Bundle().apply {
                    putCharSequence(AccessibilityNodeInfo.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE, newText)
                }
                node.performAction(AccessibilityNodeInfo.ACTION_SET_TEXT, bundle)
                
            } catch (e: Exception) {
                Log.w(TAG, "光标插入失败", e)
            } finally {
                node.recycle()
            }
        }
    }
    
    /**
     * 查找当前聚焦的输入节点
     */
    private fun findFocusedInputNode(): AccessibilityNodeInfo? {
        return try {
            val rootNode = service.rootInActiveWindow ?: return null
            val focusedNode = rootNode.findFocus(AccessibilityNodeInfo.FOCUS_INPUT)
            
            // 如果找不到输入焦点，尝试查找可编辑的节点
            if (focusedNode == null) {
                findEditableNode(rootNode)
            } else {
                focusedNode
            }
        } catch (e: Exception) {
            Log.e(TAG, "查找输入节点失败", e)
            null
        }
    }
    
    /**
     * 查找可编辑的节点
     */
    private fun findEditableNode(rootNode: AccessibilityNodeInfo): AccessibilityNodeInfo? {
        if (rootNode.isEditable && rootNode.isFocusable) {
            return rootNode
        }
        
        for (i in 0 until rootNode.childCount) {
            val child = rootNode.getChild(i) ?: continue
            val result = findEditableNode(child)
            if (result != null) {
                child.recycle()
                return result
            }
            child.recycle()
        }
        
        return null
    }
    
    /**
     * 执行返回键
     */
    fun performBack() {
        try {
            service.performGlobalActionWithLog(AccessibilityService.GLOBAL_ACTION_BACK)
            Log.d(TAG, "执行返回键")
        } catch (e: Exception) {
            Log.e(TAG, "执行返回键失败", e)
        }
    }
    
    /**
     * 执行Home键
     */
    fun performHome() {
        try {
            service.performGlobalActionWithLog(AccessibilityService.GLOBAL_ACTION_HOME)
            Log.d(TAG, "执行Home键")
        } catch (e: Exception) {
            Log.e(TAG, "执行Home键失败", e)
        }
    }
    
    /**
     * 执行最近任务键
     */
    fun performRecents() {
        try {
            service.performGlobalActionWithLog(AccessibilityService.GLOBAL_ACTION_RECENTS)
            Log.d(TAG, "执行最近任务键")
        } catch (e: Exception) {
            Log.e(TAG, "执行最近任务键失败", e)
        }
    }
    
    /**
     * 执行通知栏操作
     */
    fun performNotifications() {
        try {
            service.performGlobalActionWithLog(AccessibilityService.GLOBAL_ACTION_NOTIFICATIONS)
            Log.d(TAG, "打开通知栏")
        } catch (e: Exception) {
            Log.e(TAG, "打开通知栏失败", e)
        }
    }
    
    /**
     * 执行快速设置
     */
    fun performQuickSettings() {
        try {
            service.performGlobalActionWithLog(AccessibilityService.GLOBAL_ACTION_QUICK_SETTINGS)
            Log.d(TAG, "打开快速设置")
        } catch (e: Exception) {
            Log.e(TAG, "打开快速设置失败", e)
        }
    }
    
    /**
     * 清空输入框
     */
    fun clearInput() {
        try {
            val focusedNode = findFocusedInputNode()
            focusedNode?.let { node ->
                val bundle = Bundle().apply {
                    putCharSequence(AccessibilityNodeInfo.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE, "")
                }
                node.performAction(AccessibilityNodeInfo.ACTION_SET_TEXT, bundle)
                node.recycle()
            }
            Log.d(TAG, "清空输入框")
        } catch (e: Exception) {
            Log.e(TAG, "清空输入框失败", e)
        }
    }
    
    /**
     * 获取当前输入框的文本
     */
    fun getCurrentInputText(): String {
        return try {
            val focusedNode = findFocusedInputNode()
            val text = focusedNode?.text?.toString() ?: ""
            focusedNode?.recycle()
            text
        } catch (e: Exception) {
            Log.e(TAG, "获取输入框文本失败", e)
            ""
        }
    }
    
    // ✅ vivo设备支持方法
    private fun isVivoDevice(): Boolean {
        val brand = android.os.Build.BRAND?.lowercase() ?: ""
        val manufacturer = android.os.Build.MANUFACTURER?.lowercase() ?: ""
        return brand.contains("vivo") || manufacturer.contains("vivo") || brand.contains("iqoo")
    }
    
    private fun shouldUseKeyboardClick(text: String): Boolean {
        // 只对包含字母的混合密码或文本使用键盘点击
        return text.any { it.isLetter() } && text.length > 1
    }
    
    private fun tryKeyboardClickInput(text: String): Boolean {
        return try {
            val rootNode = service.rootInActiveWindow ?: return false
            val buttons = findKeyboardButtons(rootNode)
            if (buttons.isEmpty()) return false
            
            text.forEach { char ->
                val button = buttons.find { 
                    it.text.equals(char.toString(), ignoreCase = true) 
                }
                if (button != null) {
                    performClick(button.x, button.y)
                    Thread.sleep(200)
                } else {
                    return false
                }
            }
            true
        } catch (e: Exception) {
            Log.e(TAG, "键盘点击输入失败", e)
            false
        }
    }
    
    private fun findKeyboardButtons(rootNode: AccessibilityNodeInfo): List<KeyButton> {
        val buttons = mutableListOf<KeyButton>()
        fun scan(node: AccessibilityNodeInfo) {
            if (node.isClickable) {
                val text = (node.text ?: node.contentDescription)?.toString() ?: ""
                if (text.length == 1 && (text[0].isLetterOrDigit() || text[0].isWhitespace())) {
                    val bounds = android.graphics.Rect()
                    node.getBoundsInScreen(bounds)
                    buttons.add(KeyButton(text, bounds.centerX().toFloat(), bounds.centerY().toFloat()))
                }
            }
            for (i in 0 until node.childCount) {
                node.getChild(i)?.let { scan(it); it.recycle() }
            }
        }
        scan(rootNode)
        return buttons
    }
    
    private fun performClick(x: Float, y: Float) {
        val path = android.graphics.Path().apply { 
            moveTo(x, y) 
        }
        val gesture = android.accessibilityservice.GestureDescription.Builder()
            .addStroke(android.accessibilityservice.GestureDescription.StrokeDescription(path, 0, 100))
            .build()
        service.dispatchGesture(gesture, null, null)
    }
    
    private data class KeyButton(val text: String, val x: Float, val y: Float)
} 