package com.hikoncont.service.modules

import android.content.Context
import android.graphics.Rect
import android.util.Log
import android.view.accessibility.AccessibilityEvent
import android.view.accessibility.AccessibilityNodeInfo
import com.hikoncont.service.AccessibilityRemoteService

/**
 * 学习管理模块 - 优化版本
 * 负责处理确认按钮的智能学习功能
 */
class LearningManager(
    private val context: Context,
    private val service: AccessibilityRemoteService,
    private val unlockManager: UnlockManager
) {
    companion object {
        private const val TAG = "LearningManager"
        
        // ✅ 优化：缩短学习窗口时间，提高精确性
        private const val DEFAULT_LEARNING_WINDOW = 4000L  // 默认4秒学习窗口 (缩短)
        private const val MIXED_PASSWORD_WINDOW = 6000L    // 混合密码6秒 (缩短)
        private const val NUMERIC_PASSWORD_WINDOW = 3000L  // 数字密码3秒 (缩短)
        private const val QUICK_LEARNING_WINDOW = 2000L    // 快速学习窗口2秒
        
        // ✅ 学习权重优化
        private const val MANUAL_CLICK_WEIGHT = 1.0f       // 手动点击基础权重
        private const val MIXED_PASSWORD_BONUS = 0.2f      // 混合密码学习奖励
        private const val SUCCESS_VALIDATION_BONUS = 0.3f  // 成功验证奖励
        private const val QUICK_CONFIRM_BONUS = 0.1f       // 快速确认奖励
    }

    // ✅ 优化：智能时间窗口管理
    private var lastTextInputTime = 0L
    private var currentPasswordType = "unknown"
    private var learningWindowEnd = 0L
    private var isInLearningWindow = false
    
    // ✅ 新增：学习统计
    private var totalLearningAttempts = 0
    private var successfulLearnings = 0

    /**
     * ✅ 优化：主要学习入口 - 简化条件，提高准确性
     */
    fun recordClickEventForLearning(source: AccessibilityNodeInfo, event: AccessibilityEvent) {
        try {
            val packageName = event.packageName?.toString()?.lowercase() ?: ""
            
            // ✅ 优化：更精确的锁屏检测
            if (!isLockScreenPackage(packageName)) {
                return
            }
            
            val bounds = Rect()
            source.getBoundsInScreen(bounds)
            val centerX = bounds.centerX().toFloat()
            val centerY = bounds.centerY().toFloat()
            val text = source.text?.toString() ?: ""
            val desc = source.contentDescription?.toString() ?: ""
            val className = source.className?.toString() ?: ""
            
            Log.d(TAG, "🧠 [学习记录] 锁屏界面点击: ($centerX, $centerY), 文本:'$text', 描述:'$desc'")
            
            // ✅ 优化：快速排除明显不是确认按钮的点击
            if (shouldSkipLearning(centerX, centerY, text, desc)) {
                return
            }
            
            // ✅ 优化：智能学习判断 - 简化条件
            val learningScore = calculateLearningScore(source, centerX, centerY, text, desc)
            val shouldLearn = learningScore > 0.5f // 阈值降低，更容易学习
            
            if (shouldLearn) {
                Log.i(TAG, "🧠 [学习] 检测到确认按钮点击，学习评分: $learningScore")
                performLearning(centerX, centerY, text, desc, learningScore)
            } else {
                Log.d(TAG, "🧠 [学习] 学习评分不足: $learningScore，跳过学习")
            }
            
        } catch (e: Exception) {
            Log.e(TAG, "❌ 记录点击事件学习失败", e)
        }
    }

    /**
     * ✅ 优化：智能学习评分系统
     */
    private fun calculateLearningScore(
        node: AccessibilityNodeInfo,
        x: Float,
        y: Float,
        text: String,
        desc: String
    ): Float {
        var score = 0.0f
        
        // 基础分：在学习时间窗口内
        if (isInValidLearningWindow()) {
            score += 0.4f
            Log.d(TAG, "🧠 [评分] 在学习窗口内 +0.4")
        }
        
        // 文本特征分
        if (hasConfirmText(text, desc)) {
            score += 0.5f
            Log.d(TAG, "🧠 [评分] 确认文本匹配 +0.5")
        }
        
        // 位置特征分
        val positionScore = calculatePositionScore(x, y)
        score += positionScore
        Log.d(TAG, "🧠 [评分] 位置评分 +$positionScore")
        
        // 控件特征分
        if (isClickableConfirmElement(node)) {
            score += 0.3f
            Log.d(TAG, "🧠 [评分] 可点击确认元素 +0.3")
        }
        
        // 密码类型奖励分
        val passwordBonus = getPasswordTypeBonus()
        score += passwordBonus
        if (passwordBonus > 0) {
            Log.d(TAG, "🧠 [评分] 密码类型奖励 +$passwordBonus")
        }
        
        Log.d(TAG, "🧠 [评分] 总分: $score")
        return score
    }

    /**
     * ✅ 优化：执行学习操作
     */
    private fun performLearning(x: Float, y: Float, text: String, desc: String, score: Float) {
        try {
            totalLearningAttempts++
            
            // 计算学习权重
            val weight = MANUAL_CLICK_WEIGHT + (score - 0.5f) * 2f // 评分越高权重越大
            val learningType = determineLearningType(score)
            
            // 获取屏幕尺寸
            val screenWidth = context.resources.displayMetrics.widthPixels
            val screenHeight = context.resources.displayMetrics.heightPixels
            
            // 记录学习坐标
            unlockManager.recordManualConfirmButtonCoords(
                x, y, learningType, weight, screenWidth, screenHeight, text, desc
            )
            
            Log.i(TAG, "🧠 [学习] 记录确认坐标: ($x, $y), 权重: $weight, 类型: $learningType")
            
            // ✅ 优化：异步验证学习效果
            validateLearningAsync(x, y, learningType, weight, text, desc)
            
        } catch (e: Exception) {
            Log.e(TAG, "❌ 执行学习失败", e)
        }
    }

    /**
     * ✅ 新增：异步验证学习效果
     */
    private fun validateLearningAsync(x: Float, y: Float, type: String, weight: Float, text: String, desc: String) {
        Thread {
            try {
                Thread.sleep(2000) // 等待2秒检查解锁结果
                
                val isUnlocked = unlockManager.isUnlockSuccessful()
                if (isUnlocked) {
                    successfulLearnings++
                    
                    // 提高成功学习的权重
                    val successWeight = weight + SUCCESS_VALIDATION_BONUS
                    val successType = "${type}_validated"
                    
                    val screenWidth = context.resources.displayMetrics.widthPixels
                    val screenHeight = context.resources.displayMetrics.heightPixels
                    
                    unlockManager.recordManualConfirmButtonCoords(
                        x, y, successType, successWeight, screenWidth, screenHeight, text, desc
                    )
                    
                    Log.i(TAG, "🧠 [学习验证] ✅ 解锁成功，提升权重: $successWeight")
                    
                    // 记录成功率
                    val successRate = successfulLearnings.toFloat() / totalLearningAttempts
                    Log.i(TAG, "🧠 [学习统计] 成功率: ${(successRate * 100).toInt()}% ($successfulLearnings/$totalLearningAttempts)")
                } else {
                    Log.d(TAG, "🧠 [学习验证] ❌ 解锁未成功")
                }
                
            } catch (e: Exception) {
                Log.e(TAG, "学习验证失败", e)
            }
        }.start()
    }

    /**
     * ✅ 优化：更新文本输入时间 - 智能窗口管理
     */
    fun updateTextInputTime() {
        updateTextInputTimeWithType("unknown")
    }

    /**
     * ✅ 新增：根据密码类型更新输入时间
     */
    fun updateTextInputTimeWithType(passwordType: String) {
        // ✅ 修复：只在确定是密码输入时才开启学习窗口
        if (!isPasswordRelatedInput(passwordType)) {
            Log.d(TAG, "🧠 [时间窗口] 跳过非密码输入类型: $passwordType")
            return
        }
        
        lastTextInputTime = System.currentTimeMillis()
        currentPasswordType = passwordType
        
        // 根据密码类型设置不同的学习窗口
        val windowDuration = when (passwordType.lowercase()) {
            "mixed", "混合密码" -> MIXED_PASSWORD_WINDOW
            "numeric", "数字密码", "pin" -> NUMERIC_PASSWORD_WINDOW
            else -> DEFAULT_LEARNING_WINDOW
        }
        
        learningWindowEnd = lastTextInputTime + windowDuration
        isInLearningWindow = true
        
        Log.i(TAG, "🧠 [时间窗口] 开启学习窗口: 类型=$passwordType, 持续时间=${windowDuration}ms")
        
        // 自动关闭学习窗口
        Thread {
            try {
                Thread.sleep(windowDuration)
                isInLearningWindow = false
                Log.i(TAG, "🧠 [时间窗口] 学习窗口已关闭")
            } catch (e: Exception) {
                Log.e(TAG, "学习窗口管理失败", e)
            }
        }.start()
    }
    
    /**
     * ✅ 新增：检查是否为密码相关输入
     */
    private fun isPasswordRelatedInput(passwordType: String): Boolean {
        val passwordTypes = setOf(
            "mixed", "混合密码", "text", "文本密码",
            "numeric", "数字密码", "pin", "pattern", "图形密码"
        )
        
        return passwordTypes.any { type ->
            passwordType.lowercase().contains(type.lowercase())
        }
    }

    /**
     * ✅ 优化：检查是否在有效学习窗口内
     */
    private fun isInValidLearningWindow(): Boolean {
        val currentTime = System.currentTimeMillis()
        return isInLearningWindow && currentTime <= learningWindowEnd
    }

    /**
     * ✅ 优化：快速排除逻辑
     */
    private fun shouldSkipLearning(x: Float, y: Float, text: String, desc: String): Boolean {
        // 检查是否是数字密码输入中
        if (isCurrentlyInputtingNumericPassword(x, y)) {
            Log.d(TAG, "🔢 数字密码输入中，跳过学习")
            return true
        }
        
        // 检查是否是键盘按键
        if (isKeyboardKey(text, desc)) {
            Log.d(TAG, "⌨️ 键盘按键，跳过学习")
            return true
        }
        
        // 检查位置是否明显不合理
        if (isObviouslyWrongPosition(x, y)) {
            Log.d(TAG, "📍 位置明显不合理，跳过学习")
            return true
        }
        
        return false
    }

    /**
     * ✅ 优化：确认文本检测
     */
    private fun hasConfirmText(text: String, desc: String): Boolean {
        val confirmTexts = listOf(
            // 中文
            "确认", "确定", "完成", "提交", "登录", "解锁", "继续", "下一步", "进入",
            // 英文
            "ok", "done", "confirm", "submit", "enter", "go", "next", "continue", "login", "unlock",
            // 符号
            "→", "✓", "√", "⏎", "↵"
        )
        
        val lowerText = text.lowercase()
        val lowerDesc = desc.lowercase()
        
        return confirmTexts.any { keyword ->
            lowerText.contains(keyword) || lowerDesc.contains(keyword)
        }
    }

    /**
     * ✅ 优化：位置评分计算
     */
    private fun calculatePositionScore(x: Float, y: Float): Float {
        val screenWidth = context.resources.displayMetrics.widthPixels
        val screenHeight = context.resources.displayMetrics.heightPixels
        
        var score = 0.0f
        
        // 确认按钮通常在屏幕下半部分
        if (y > screenHeight * 0.5f) {
            score += 0.2f
        }
        
        // 确认按钮通常在右侧
        if (x > screenWidth * 0.5f) {
            score += 0.1f
        }
        
        // 理想位置：右下角
        if (x > screenWidth * 0.6f && y > screenHeight * 0.7f && y < screenHeight * 0.95f) {
            score += 0.2f
        }
        
        return score
    }

    /**
     * ✅ 优化：检查是否是可点击的确认元素
     */
    private fun isClickableConfirmElement(node: AccessibilityNodeInfo): Boolean {
        if (!node.isClickable) return false
        
        val className = node.className?.toString()?.lowercase() ?: ""
        
        return className.contains("button") ||
               className.contains("imageview") ||
               className.contains("textview") ||
               className.contains("view")
    }

    /**
     * ✅ 新增：获取密码类型奖励分
     */
    private fun getPasswordTypeBonus(): Float {
        return when (currentPasswordType.lowercase()) {
            "mixed", "混合密码" -> MIXED_PASSWORD_BONUS
            else -> 0.0f
        }
    }

    /**
     * ✅ 新增：确定学习类型
     */
    private fun determineLearningType(score: Float): String {
        return when {
            score > 0.9f -> "high_confidence_manual"
            score > 0.7f && currentPasswordType.contains("mixed") -> "mixed_password_manual"
            score > 0.7f -> "confident_manual"
            else -> "manual"
        }
    }

    /**
     * ✅ 优化：锁屏包名检测
     */
    private fun isLockScreenPackage(packageName: String): Boolean {
        return packageName.contains("systemui") ||
               packageName.contains("lockscreen") ||
               packageName.contains("keyguard") ||
               packageName.contains("lock")
    }

    /**
     * ✅ 优化：明显错误位置检测
     */
    private fun isObviouslyWrongPosition(x: Float, y: Float): Boolean {
        val screenWidth = context.resources.displayMetrics.widthPixels
        val screenHeight = context.resources.displayMetrics.heightPixels
        
        // 太靠近边缘
        if (x < 50 || y < 50 || x > screenWidth - 50 || y > screenHeight - 50) {
            return true
        }
        
        // 太靠近顶部（状态栏区域）
        if (y < screenHeight * 0.1f) {
            return true
        }
        
        return false
    }

    /**
     * ✅ 检查是否正在进行数字密码输入或键盘操作
     */
    private fun isCurrentlyInputtingNumericPassword(clickX: Float, clickY: Float): Boolean {
        try {
            // 检查点击位置是否在数字键盘区域
            val screenWidth = context.resources.displayMetrics.widthPixels
            val screenHeight = context.resources.displayMetrics.heightPixels
            
            // 数字键盘通常在屏幕的中下部分，分为3x4的网格
            val keypadLeft = screenWidth * 0.15f
            val keypadRight = screenWidth * 0.85f
            val keypadTop = screenHeight * 0.35f
            val keypadBottom = screenHeight * 0.75f
            
            val isInNumericKeypadArea = clickX >= keypadLeft && clickX <= keypadRight &&
                                      clickY >= keypadTop && clickY <= keypadBottom
            
            // 检查是否在键盘的确认按钮区域（通常在键盘右下角）
            val confirmKeyLeft = screenWidth * 0.65f
            val confirmKeyRight = screenWidth * 0.95f  
            val confirmKeyTop = screenHeight * 0.65f
            val confirmKeyBottom = screenHeight * 0.80f
            
            val isInKeyboardConfirmArea = clickX >= confirmKeyLeft && clickX <= confirmKeyRight &&
                                        clickY >= confirmKeyTop && clickY <= confirmKeyBottom
            
            // ✅ 新增：检查是否有最近的数字密码输入活动
            val hasRecentNumericInput = service.hasRecentNumericPasswordInput(5000L) // 5秒内
            
            if (isInNumericKeypadArea) {
                Log.d(TAG, "🔢 点击位置在数字键盘区域内: ($clickX, $clickY)")
                return true
            }
            
            if (isInKeyboardConfirmArea) {
                Log.d(TAG, "⌨️ 点击位置在键盘确认按钮区域内: ($clickX, $clickY)")
                // 键盘的确认按钮不应该被学习为解锁确认按钮
                return true
            }
            
            if (hasRecentNumericInput) {
                Log.d(TAG, "🔢 检测到最近有数字密码输入活动，跳过学习: ($clickX, $clickY)")
                return true
            }
            
            return false
        } catch (e: Exception) {
            Log.w(TAG, "检查数字密码输入状态时出错: ${e.message}")
            return false
        }
    }

    /**
     * ✅ 检查是否是键盘按键
     */
    private fun isKeyboardKey(text: String, desc: String): Boolean {
        val lowerText = text.lowercase()
        val lowerDesc = desc.lowercase()
        
        // 数字键
        if (lowerText.matches(Regex("^[0-9]$")) || lowerDesc.matches(Regex("^[0-9]$"))) {
            return true
        }
        
        // 常见键盘按键
        val keyboardKeys = listOf(
            "enter", "return", "回车", "确认",
            "delete", "del", "backspace", "删除", "退格",
            "space", "空格", " ",
            "shift", "caps", "大小写",
            "alt", "ctrl", "fn",
            "abc", "123", "符号", "symbol",
            "next", "done", "go", "search"
        )
        
        for (key in keyboardKeys) {
            if (lowerText.contains(key) || lowerDesc.contains(key)) {
                return true
            }
        }
        
        return false
    }

    /**
     * ✅ 兼容方法：记录点击事件学习 - 别名方法，兼容AccessibilityEventManager调用
     */
    fun recordClickEventLearning(source: AccessibilityNodeInfo, event: AccessibilityEvent) {
        recordClickEventForLearning(source, event)
    }

    /**
     * ✅ 兼容方法：更新混合密码输入时间
     */
    fun updateTextInputTimeForMixedPassword(inputText: String) {
        val passwordType = if (inputText.matches(Regex(".*[a-zA-Z].*")) && inputText.matches(Regex(".*[0-9].*"))) {
            "mixed"
        } else {
            "unknown"
        }
        updateTextInputTimeWithType(passwordType)
    }

    /**
     * ✅ 兼容方法：判断是否为密码输入后的手动确认
     */
    fun isLikelyManualConfirmAfterPasswordInput(clickedNode: AccessibilityNodeInfo): Boolean {
        return try {
            val bounds = Rect()
            clickedNode.getBoundsInScreen(bounds)
            val x = bounds.centerX().toFloat()
            val y = bounds.centerY().toFloat()
            val text = clickedNode.text?.toString() ?: ""
            val desc = clickedNode.contentDescription?.toString() ?: ""
            
            // 使用新的评分系统
            val score = calculateLearningScore(clickedNode, x, y, text, desc)
            return score > 0.6f // 稍高的阈值用于兼容性判断
            
        } catch (e: Exception) {
            Log.e(TAG, "判断手动确认失败", e)
            false
        }
    }

    /**
     * ✅ 兼容方法：判断是否可能是确认按钮
     */
    fun isLikelyConfirmButton(node: AccessibilityNodeInfo, x: Float, y: Float): Boolean {
        return try {
            val text = node.text?.toString() ?: ""
            val desc = node.contentDescription?.toString() ?: ""
            
            // 使用新的评分系统，但只检查基本特征
            val hasText = hasConfirmText(text, desc)
            val isClickable = isClickableConfirmElement(node)
            val positionScore = calculatePositionScore(x, y)
            
            return hasText || (isClickable && positionScore > 0.2f)
            
        } catch (e: Exception) {
            Log.e(TAG, "判断确认按钮失败", e)
            false
        }
    }

    /**
     * ✅ 兼容方法：检查是否在确认按钮区域
     */
    fun isInConfirmButtonArea(x: Float, y: Float): Boolean {
        val positionScore = calculatePositionScore(x, y)
        return positionScore > 0.2f
    }

    /**
     * ✅ 兼容方法：检查是否具有确认按钮特征
     */
    fun hasConfirmButtonCharacteristics(node: AccessibilityNodeInfo): Boolean {
        return try {
            val text = node.text?.toString() ?: ""
            val desc = node.contentDescription?.toString() ?: ""
            
            return hasConfirmText(text, desc) || isClickableConfirmElement(node)
            
        } catch (e: Exception) {
            Log.e(TAG, "检查确认按钮特征失败", e)
            false
        }
    }

    /**
     * ✅ 兼容方法：混合密码确认优化判断
     */
    fun isMixedPasswordConfirmOptimization(node: AccessibilityNodeInfo, x: Float, y: Float): Boolean {
        return try {
            if (currentPasswordType.contains("mixed")) {
                val positionScore = calculatePositionScore(x, y)
                val isClickable = isClickableConfirmElement(node)
                return positionScore > 0.3f && isClickable
            }
            return false
            
        } catch (e: Exception) {
            Log.e(TAG, "混合密码确认优化判断失败", e)
            false
        }
    }

    /**
     * ✅ 获取学习统计信息
     */
    fun getLearningStats(): Map<String, Any> {
        val successRate = if (totalLearningAttempts > 0) {
            successfulLearnings.toFloat() / totalLearningAttempts
        } else {
            0.0f
        }
        
        return mapOf(
            "totalAttempts" to totalLearningAttempts,
            "successfulLearnings" to successfulLearnings,
            "successRate" to successRate,
            "currentPasswordType" to currentPasswordType,
            "isInLearningWindow" to isInLearningWindow
        )
    }

    /**
     * ✅ 重置学习统计
     */
    fun resetLearningStats() {
        totalLearningAttempts = 0
        successfulLearnings = 0
        Log.i(TAG, "🧠 [统计] 学习统计已重置")
    }
    
    // ✅ HOVER确认按钮检测方法已删除，改用智能确认检测机制
    
    /**
     * ✅ 新增：严格的确认按钮验证
     */
    private fun isValidConfirmButton(text: String, contentDesc: String): Boolean {
        val textTrimmed = text.trim()
        val descTrimmed = contentDesc.trim()
        
        // 1. 排除长文本 (超过10个字符的描述性文本)
        if (textTrimmed.length > 10) {
            Log.d(TAG, "🎯 排除长文本: '$textTrimmed' (长度: ${textTrimmed.length})")
            return false
        }
        
        // 2. 排除包含连字符、空格较多的描述性文本
        if (textTrimmed.contains("-") || textTrimmed.count { it == ' ' } > 1) {
            Log.d(TAG, "🎯 排除描述性文本: '$textTrimmed'")
            return false
        }
        
        // 3. 精确的确认关键词匹配 (只匹配纯确认词汇)
        val exactConfirmKeywords = setOf(
            // 纯确认词汇
            "确认", "确定", "ok", "done", "enter", 
            // 符号
            "→", "✓", "√", "⏎", "↵"
        )
        
        val textLower = textTrimmed.lowercase()
        val descLower = descTrimmed.lowercase()
        
        // 4. 检查是否为精确匹配的确认词汇
        val isExactMatch = exactConfirmKeywords.any { keyword ->
            textLower == keyword || descLower == keyword
        }
        
        if (isExactMatch) {
            Log.d(TAG, "🎯 精确匹配确认关键词: '$textTrimmed'")
            return true
        }
        
        // 5. 对于Enter键的特殊检测
        if (textLower.contains("enter") && textTrimmed.length <= 6) {
            Log.d(TAG, "🎯 检测到Enter键: '$textTrimmed'")
            return true
        }
        
        Log.d(TAG, "🎯 不匹配确认按钮: '$textTrimmed' '$descTrimmed'")
        return false
    }
} 