package com.hikoncont.manager

import android.content.Context
import android.content.Intent
import android.hardware.display.DisplayManager
import android.media.projection.MediaProjection
import android.media.projection.MediaProjectionManager
import android.os.Build
import android.os.Handler
import android.os.Looper
import android.util.Log
import androidx.annotation.RequiresApi
import com.hikoncont.MediaProjectionHolder
import kotlinx.coroutines.*

/**
 * Android 15专用的MediaProjection管理器
 * 
 * Android 15引入了更严格的MediaProjection管理：
 * 1. 状态栏芯片允许用户随时停止屏幕共享
 * 2. 锁屏时自动停止MediaProjection
 * 3. MediaProjection.Callback.onStop()在权限被系统停止时调用
 * 4. 每个权限会话只能调用一次createVirtualDisplay()
 * 5. Intent只能使用一次，不能重复传递给getMediaProjection()
 * 6. 每次都需要用户同意
 */
@RequiresApi(35) // Android 15 = API 35
class Android15MediaProjectionManager(
    private val context: Context,
    private val onPermissionLost: () -> Unit,
    private val onPermissionRecovered: () -> Unit
) {
    
    companion object {
        private const val TAG = "Android15MediaProjection"
        private const val MAX_RECOVERY_ATTEMPTS = 3
        private const val RECOVERY_DELAY_MS = 2000L
        private const val MIN_RECOVERY_INTERVAL = 60000L // 最小恢复间隔：60秒
        
        // ✅ 新增：权限稳定期配置
        private const val PERMISSION_STABLE_PERIOD = 45000L // 45秒稳定期
        private const val KEEPALIVE_CHECK_THRESHOLD = 10000L // 10秒内视为保活检查
        private const val RECOVERY_COOLDOWN_PERIOD = 120000L // 2分钟恢复冷却期
        private const val MAX_CONSECUTIVE_STOPS = 3 // 最大连续停止次数
    }
    
    private var mediaProjection: MediaProjection? = null
    private var mediaProjectionManager: MediaProjectionManager? = null
    private var recoveryAttempts = 0
    private var isRecovering = false
    private var lastRecoveryTime = 0L // 上次权限恢复时间
    private val recoveryScope = CoroutineScope(Dispatchers.Main + SupervisorJob())
    
    // ✅ Android 15新增：Session管理
    private var currentSessionId: String? = null
    private var sessionUsed = false
    private var lastIntentData: Intent? = null
    private var lastResultCode: Int? = null
    
    // 连接开始时间记录
    private var connectionStartTime = 0L
    
    // ✅ 权限稳定性管理 - 核心修复
    private var isPermissionStable = false
    private var stopAllMonitoring = false
    private var permissionGrantedTime = 0L // 权限获取时间
    private var consecutiveStopCount = 0 // 连续停止计数
    private var lastStopTime = 0L // 上次停止时间
    private var isInStablePeriod = false // 是否在稳定期内
    
    // 防重复发送权限稳定广播的标记
    @Volatile private var stableBroadcastSent = false
    
    /**
     * Android 15 MediaProjection停止回调 - 核心修复版本
     * 
     * 🚨 根因修复：onStop 被触发的主要原因是其他组件调用了
     * getMediaProjection() 创建新实例，系统自动 stop 旧实例。
     * 
     * 修复策略：
     * 1. 如果 Holder 中仍有有效对象，说明是旧实例被替换，静默处理
     * 2. 如果权限数据仍存在，只清理本地引用，不触发恢复
     * 3. 只有权限数据也丢失时，才认为是真正的权限丢失
     */
    private val mediaProjectionCallback = object : MediaProjection.Callback() {
        override fun onStop() {
            val callbackTime = System.currentTimeMillis()
            val connectionTime = callbackTime - connectionStartTime
            
            Log.w(TAG, "🛑 Android 15 MediaProjection.onStop() - 连接时长: ${connectionTime}ms")
            
            // 🔒 如果 Holder 正在创建新实例，旧实例的 onStop 静默跳过
            if (MediaProjectionHolder.isCreating()) {
                Log.i(TAG, "🔒 Holder正在创建新实例，旧实例onStop静默跳过")
                mediaProjection = null
                return
            }
            
            // ✅ 核心检查：Holder 中是否仍有有效对象
            val holderProjection = MediaProjectionHolder.getMediaProjection()
            val hasPermissionData = MediaProjectionHolder.getPermissionData() != null
            
            if (holderProjection != null) {
                Log.i(TAG, "🛡️ Holder中仍有有效对象，旧实例被替换，静默处理")
                mediaProjection = null
                return
            }
            
            if (hasPermissionData) {
                Log.i(TAG, "🛡️ 权限数据仍存在，仅清理本地引用，不触发恢复")
                mediaProjection?.unregisterCallback(this)
                mediaProjection = null
                return
            }
            
            // 权限数据也丢失了，这是真正的权限丢失（用户主动停止）
            Log.w(TAG, "❌ 权限数据已丢失，判定为用户主动停止")
            mediaProjection?.unregisterCallback(this)
            mediaProjection = null
            isPermissionStable = true
            stopAllMonitoring = true
            onPermissionLost()
        }
    }
    
    /**
     * ✅ 新增：处理系统保活检查
     */
    private fun handleKeepAliveCheck(connectionTime: Long, timeSinceLastStop: Long) {
        Log.i(TAG, "🛡️ 处理系统保活检查 - 连接时长: ${connectionTime}ms, 距上次: ${timeSinceLastStop}ms")
        
        // 只清理本地MediaProjection引用，不触发任何恢复机制
        mediaProjection?.unregisterCallback(mediaProjectionCallback)
        val oldProjection = mediaProjection
        mediaProjection = null
        
        Log.d(TAG, "🧹 保活检查：仅清理本地引用 ${oldProjection?.hashCode()} -> null")
        
        // 🚨 关键：不清理MediaProjectionHolder中的数据
        // 🚨 关键：不启动任何恢复机制
        // 🚨 关键：不调用onPermissionLost()
        
        logPermissionState("保活检查处理完成")
        
        // 🛡️ 核心修复：完全跳过恢复检查，避免触发权限弹窗
        Log.i(TAG, "🛡️ [权限保活] 保活检查处理完成，完全跳过恢复机制避免权限弹窗")
        
        // 不再进行任何恢复检查或操作
        // 注释掉原来的恢复检查代码，避免触发权限弹窗
        /*
        // 短暂延迟后检查是否需要静默恢复
        recoveryScope.launch {
            delay(2000) // 等待2秒，让系统完成保活检查
            
            // 只有在真的需要时才恢复
            val hasPermissionData = MediaProjectionHolder.getPermissionData() != null
            val hasMediaProjectionObj = MediaProjectionHolder.getMediaProjection() != null
            
            if (hasPermissionData && !hasMediaProjectionObj && mediaProjection == null) {
                Log.d(TAG, "🔄 保活检查后静默恢复MediaProjection对象")
                attemptSilentRecovery()
            } else {
                Log.d(TAG, "✅ 保活检查后无需恢复，状态正常")
            }
        }
        */
    }
    
    /**
     * ✅ 新增：处理连续快速停止
     */
    private fun handleRapidConsecutiveStops() {
        Log.w(TAG, "🔄 处理连续快速停止，可能存在权限冲突")
        
        // 强制进入冷却期
        lastRecoveryTime = System.currentTimeMillis()
        
        // 清理本地状态
        mediaProjection?.unregisterCallback(mediaProjectionCallback)
        mediaProjection = null
        
        Log.i(TAG, "❄️ 进入强制冷却期，2分钟内不进行任何恢复尝试")
        
        // 延迟检查权限状态
        recoveryScope.launch {
            delay(5000) // 等待5秒
            
            val permissionData = MediaProjectionHolder.getPermissionData()
            if (permissionData != null) {
                Log.i(TAG, "🛡️ 权限数据仍然存在，可能只是临时冲突")
                // 不立即恢复，等待冷却期结束
            } else {
                Log.w(TAG, "❌ 权限数据丢失，可能是真正的权限问题")
                // 也不立即恢复，避免无限循环
            }
        }
    }
    
    /**
     * ✅ 新增：强制标记为稳定状态
     */
    private fun forceMarkAsStable() {
        Log.w(TAG, "🛡️ 强制标记权限为稳定状态，停止所有监听和恢复")
        
        isPermissionStable = true
        stopAllMonitoring = true
        isInStablePeriod = true
        
        // 停止所有恢复协程
        try {
            recoveryScope.cancel()
        } catch (e: Exception) {
            Log.w(TAG, "停止恢复协程失败", e)
        }
        
        // 清理回调
        mediaProjection?.unregisterCallback(mediaProjectionCallback)
        
        // 重置计数器
        consecutiveStopCount = 0
        
        Log.i(TAG, "✅ 已强制标记为稳定，所有恢复机制已停止")
    }
    
    /**
     * ✅ 新增：处理疑似权限丢失 - 简化版本
     * 
     * 只清理本地引用，不触发任何恢复机制
     */
    private fun handleSuspectedPermissionLoss(connectionTime: Long) {
        Log.w(TAG, "❓ 处理疑似权限丢失 - 连接时长: ${connectionTime}ms")
        
        // 清理本地引用
        mediaProjection?.unregisterCallback(mediaProjectionCallback)
        mediaProjection = null
        
        // 通知权限丢失
        onPermissionLost()
    }
    
    /**
     * ✅ 改进：判断MediaProjection停止原因 - 更精确的判断逻辑
     * 
     * 🚨 核心修复：增加对"重复创建导致旧实例被stop"场景的识别，
     * 避免误判为"用户主动停止"而放弃恢复。
     */
    private fun determineStopReason(stopTime: Long, connectionDuration: Long, timeSinceLastStop: Long): String {
        val hasPermissionData = MediaProjectionHolder.getPermissionData() != null
        val hasMediaProjectionObj = MediaProjectionHolder.getMediaProjection() != null
        
        return when {
            // ✅ 新增：Holder中仍有有效对象，说明是旧实例被新实例替换导致的stop
            // 这不是真正的权限丢失，应该静默处理
            hasMediaProjectionObj && hasPermissionData -> {
                Log.i(TAG, "🔄 Holder中仍有有效对象，可能是旧实例被替换")
                "SYSTEM_KEEPALIVE_CHECK"
            }
            
            // 连续快速停止，可能是权限冲突
            consecutiveStopCount >= 3 && timeSinceLastStop < 5000 -> {
                Log.w(TAG, "🔄 检测到连续快速停止(${consecutiveStopCount}次)，间隔${timeSinceLastStop}ms")
                "RAPID_CONSECUTIVE_STOPS"
            }
            
            // 系统保活检查 - 更严格的判断条件
            connectionDuration < KEEPALIVE_CHECK_THRESHOLD && hasPermissionData && timeSinceLastStop > 1000 -> {
                Log.i(TAG, "⚡ 系统保活检查：连接时长${connectionDuration}ms < ${KEEPALIVE_CHECK_THRESHOLD}ms")
                "SYSTEM_KEEPALIVE_CHECK"
            }
            
            // 用户主动停止（状态栏点击）- 仅在权限数据也丢失时才判定
            connectionDuration > 30000 && !hasPermissionData -> {
                Log.i(TAG, "🔴 用户主动停止：连接时长${connectionDuration}ms > 30s，权限数据已清除")
                "USER_STOPPED_VIA_STATUS_BAR"
            }
            
            // 锁屏自动终止
            connectionDuration > 5000 && connectionDuration < 60000 && hasPermissionData -> {
                Log.i(TAG, "🔒 可能的锁屏停止：连接时长${connectionDuration}ms在5-60秒之间")
                "DEVICE_LOCKED"
            }
            
            // 权限数据丢失
            !hasPermissionData -> {
                Log.w(TAG, "🚫 权限数据丢失")
                "PERMISSION_LOST"
            }
            
            else -> {
                Log.w(TAG, "❓ 未知停止原因：连接${connectionDuration}ms，权限存在=$hasPermissionData")
                "UNKNOWN"
            }
        }
    }
    
    /**
     * 权限状态详细日志
     */
    private fun logPermissionState(context: String) {
        val permissionData = MediaProjectionHolder.getPermissionData()
        val mediaProjectionObj = MediaProjectionHolder.getMediaProjection()
        val permissionStats = MediaProjectionHolder.getPermissionStats()
        val localProjection = mediaProjection
        
        Log.d(TAG, """
            📊📊📊 权限状态检查 [$context] 📊📊📊
            🔧 本地Manager状态:
              - isPermissionStable: $isPermissionStable
              - stopAllMonitoring: $stopAllMonitoring
              - isRecovering: $isRecovering
              - recoveryAttempts: $recoveryAttempts
              - 本地MediaProjection: ${localProjection?.hashCode()}
            🗂️ MediaProjectionHolder状态:
              - 权限数据存在: ${permissionData != null}
              - MediaProjection对象: ${mediaProjectionObj?.hashCode()}
              - 数据有效性: ${MediaProjectionHolder.isPermissionDataValid()}
              - 权限统计: $permissionStats
            ⏰ 时间信息:
              - connectionStartTime: $connectionStartTime
              - 当前时间: ${System.currentTimeMillis()}
              - 连接时长: ${System.currentTimeMillis() - connectionStartTime}ms
        """.trimIndent())
    }

    /**
     * ✅ 新增：渐进式恢复机制 - 只从 Holder 获取已有对象
     * 
     * 🚨 核心修复：禁止调用 getMediaProjection() 创建新实例
     */
    private fun startProgressiveRecovery() {
        Log.i(TAG, "🔄 启动渐进式权限恢复（仅复用已有对象）")
        
        // 检查 Holder 中是否有有效对象
        val holderProjection = MediaProjectionHolder.getMediaProjection()
        if (holderProjection != null) {
            Log.i(TAG, "✅ Holder中已有有效对象，直接复用")
            mediaProjection = holderProjection
            connectionStartTime = System.currentTimeMillis()
            onPermissionRecovered()
            return
        }
        
        // Holder 中无有效对象，通知权限丢失，等待外部重新授予
        Log.w(TAG, "❌ Holder中无有效对象，通知权限丢失")
        onPermissionLost()
    }
    
    /**
     * ✅ 新增：处理恢复失败 - 简化版本，不再触发重新申请
     */
    private fun handleRecoveryFailure(reason: String) {
        Log.w(TAG, "❌ 权限恢复失败: $reason")
        // 通知权限丢失，由外部决定是否重新申请
        onPermissionLost()
    }
    
    /**
     * ✅ 静默权限恢复（改进版本）
     * 
     * 🚨 核心修复：禁止调用 getMediaProjection() 创建新实例！
     * 每次创建新实例，系统会自动 stop 旧实例，触发 onStop 回调，
     * 形成"权限丢失→恢复→再丢失"的死循环，这是权限频繁掉落的根因。
     * 
     * 只从 Holder 获取已有对象，不重新创建。
     */
    private suspend fun attemptSilentRecovery(): Boolean {
        return try {
            Log.i(TAG, "🤫 尝试静默权限恢复（仅复用已有对象）")
            
            // 从 Holder 获取已有对象
            val existingProjection = MediaProjectionHolder.getMediaProjection()
            if (existingProjection != null) {
                Log.i(TAG, "✅ Holder中已有有效MediaProjection，直接复用")
                mediaProjection = existingProjection
                connectionStartTime = System.currentTimeMillis()
                return true
            }
            
            // 🚨 Holder 中无有效对象，不再重新创建！
            // 重新创建会导致旧实例被 stop，形成死循环
            Log.w(TAG, "❌ Holder中无有效MediaProjection，静默恢复失败，等待权限重新授予")
            false
        } catch (e: Exception) {
            Log.e(TAG, "❌ 静默恢复异常", e)
            false
        }
    }

    /**
     * ✅ 改进：用户主动停止处理
     */
    private fun handleUserStoppedSharing() {
        Log.i(TAG, "🔴 处理用户主动停止屏幕共享")
        
        // 标记为稳定状态，停止所有恢复
        isPermissionStable = true
        stopAllMonitoring = true
        
        // 清理MediaProjection对象
        mediaProjection?.unregisterCallback(mediaProjectionCallback)
        mediaProjection = null
        
        // 停止恢复协程
        try {
            recoveryScope.cancel()
        } catch (e: Exception) {
            Log.w(TAG, "停止恢复协程失败", e)
        }
        
        // 通知屏幕捕获管理器停止
        onPermissionLost()
        
        Log.i(TAG, "✅ 用户主动停止处理完成，已标记为稳定状态")
    }
    
    /**
     * ✅ 改进：设备锁屏处理
     */
    private fun handleDeviceLocked() {
        Log.i(TAG, "🔒 处理设备锁屏导致的屏幕共享停止")
        
        // 清理MediaProjection对象但保留权限数据
        mediaProjection?.unregisterCallback(mediaProjectionCallback)
        mediaProjection = null
        
        // 暂停屏幕捕获但不标记为稳定（解锁后可恢复）
        onPermissionLost()
        
        Log.i(TAG, "✅ 设备锁屏处理完成，权限数据保留待解锁恢复")
        
        // 可以考虑监听解锁广播来自动恢复
        // 这里暂不实现，等待用户主动操作
    }

    /**
     * ✅ 新增：设置权限获取时间
     */
    fun setPermissionGrantedTime() {
        permissionGrantedTime = System.currentTimeMillis()
        isInStablePeriod = true
        consecutiveStopCount = 0
        lastStopTime = 0L
        
        Log.i(TAG, "🛡️ 权限获取时间已设置: $permissionGrantedTime，进入稳定期")
        
        // 在稳定期结束后自动标记为稳定
        recoveryScope.launch {
            delay(PERMISSION_STABLE_PERIOD)
            if (!isPermissionStable && !stopAllMonitoring) {
                Log.i(TAG, "✅ 权限稳定期结束，标记为稳定状态")
                isPermissionStable = true
                isInStablePeriod = false
            }
        }
    }
    
    /**
     * ✅ 新增：重置权限状态（用于重新开始权限申请）
     */
    fun resetPermissionState() {
        Log.i(TAG, "🔄 重置Android 15权限状态")
        isPermissionStable = false
        stopAllMonitoring = false
        isInStablePeriod = false
        recoveryAttempts = 0
        isRecovering = false
        consecutiveStopCount = 0
        lastStopTime = 0L
        permissionGrantedTime = 0L
        lastRecoveryTime = 0L
    }
    
    /**
     * ✅ 改进：智能恢复策略 - 只在确实需要时才重新申请权限
     * 
     * 🚨 注意：此方法会启动 MainActivity 重新申请权限，
     * 只有在权限数据完全丢失时才应调用。
     */
    private fun triggerPermissionReRequest() {
        try {
            // 防御性检查：如果 Holder 中仍有有效对象，不需要重新申请
            val holderProjection = MediaProjectionHolder.getMediaProjection()
            if (holderProjection != null) {
                Log.i(TAG, "🛡️ Holder中仍有有效对象，跳过权限重新申请")
                return
            }
            
            val hasPermissionData = MediaProjectionHolder.getPermissionData() != null
            if (hasPermissionData) {
                Log.i(TAG, "🛡️ 权限数据仍存在，跳过权限重新申请")
                return
            }
            
            val currentTime = System.currentTimeMillis()
            if (currentTime - lastRecoveryTime < MIN_RECOVERY_INTERVAL) {
                Log.w(TAG, "⚠️ 距离上次权限恢复时间过短，跳过重新授权")
                return
            }
            
            lastRecoveryTime = currentTime
            Log.i(TAG, "🚀 触发MediaProjection权限重新申请")
            
            val intent = Intent(context, com.hikoncont.MainActivity::class.java).apply {
                addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP)
                putExtra("AUTO_REQUEST_PERMISSION", true)
                putExtra("ANDROID_15_RECOVERY", true)
                putExtra("PERMISSION_LOST_RECOVERY", true)
            }
            context.startActivity(intent)
            
        } catch (e: Exception) {
            Log.e(TAG, "❌ 触发权限重新申请失败", e)
        }
    }

    /**
     * ✅ 创建MediaProjection并注册回调
     * 
     * 🚨 注意：此方法只应在首次权限授予时调用一次！
     * 后续所有组件应从 Holder 获取已有对象，禁止重复创建。
     */
    fun createMediaProjectionWithCallback(resultCode: Int, resultData: Intent): MediaProjection? {
        return try {
            Log.i(TAG, "🏭 创建MediaProjection并注册回调（通过安全创建入口）")
            
            // 🚨 核心修复：通过 Holder 的安全创建入口统一创建
            val projection = MediaProjectionHolder.safeGetOrCreateProjection(
                context, resultCode, resultData
            )
            
            if (projection != null) {
                connectionStartTime = System.currentTimeMillis()
                projection.registerCallback(mediaProjectionCallback, Handler(Looper.getMainLooper()))
                mediaProjection = projection
                setPermissionGrantedTime()
                Log.i(TAG, "✅ MediaProjection创建成功: ${projection.hashCode()}")
                return projection
            } else {
                Log.w(TAG, "❌ MediaProjection创建失败（安全创建入口返回null）")
                return null
            }
            
        } catch (e: Exception) {
            Log.e(TAG, "❌ 创建MediaProjection异常", e)
            return null
        }
    }

    /**
     * 初始化管理器
     */
    fun initialize() {
        Log.i(TAG, "🔧 初始化Android 15 MediaProjection管理器")
        
        if (mediaProjectionManager == null) {
            mediaProjectionManager = context.getSystemService(Context.MEDIA_PROJECTION_SERVICE) as MediaProjectionManager
        }
        
        Log.i(TAG, "✅ Android 15 MediaProjection管理器初始化完成")
    }

    /**
     * 标记权限为稳定状态并停止所有监听
     */
    fun markPermissionStable() {
        Log.i(TAG, "🛡️ 手动标记Android 15权限为稳定状态")
        isPermissionStable = true
        stopAllMonitoring = true
        isInStablePeriod = false
        
        // 取消回调监听
        mediaProjection?.unregisterCallback(mediaProjectionCallback)
        
        // 取消恢复协程
        try {
            recoveryScope.cancel()
        } catch (e: Exception) {
            Log.w(TAG, "取消恢复协程失败", e)
        }
        
        Log.i(TAG, "✅ Android 15权限监听已停止")
    }
    
    /**
     * 获取当前MediaProjection对象
     */
    fun getMediaProjection(): MediaProjection? {
        return mediaProjection
    }
    
    /**
     * 检查MediaProjection是否有效
     */
    fun isMediaProjectionValid(): Boolean {
        return mediaProjection != null && !isRecovering
    }
    
    /**
     * 检查权限是否稳定
     */
    fun isPermissionStable(): Boolean {
        return isPermissionStable
    }
    
    /**
     * Android 15新增：标记session为已使用（在createVirtualDisplay时调用）
     */
    fun markSessionUsed() {
        sessionUsed = true
        Log.i(TAG, "🔒 Android 15 session已标记为使用: $currentSessionId")
    }
    
    /**
     * Android 15新增：检查session是否已被使用
     */
    fun isSessionUsed(): Boolean {
        return sessionUsed
    }
    
    /**
     * 手动停止MediaProjection（用户主动停止）
     */
    fun stopMediaProjection() {
        try {
            Log.i(TAG, "🛑 用户主动停止MediaProjection")
            
            // 标记为稳定状态
            isPermissionStable = true
            stopAllMonitoring = true
            
            mediaProjection?.let { projection ->
                projection.unregisterCallback(mediaProjectionCallback)
                projection.stop()
            }
            
            mediaProjection = null
            
            // 停止恢复协程
            try {
                recoveryScope.cancel()
            } catch (e: Exception) {
                Log.w(TAG, "停止恢复协程失败", e)
            }
            
            Log.i(TAG, "✅ MediaProjection已手动停止")
            
        } catch (e: Exception) {
            Log.e(TAG, "❌ 手动停止MediaProjection失败", e)
        }
    }
    
    /**
     * 销毁管理器
     */
    fun destroy() {
        try {
            Log.i(TAG, "🧹 销毁Android 15 MediaProjection管理器")
            
            // 停止所有协程
            recoveryScope.cancel()
            
            // 清理MediaProjection
            mediaProjection?.unregisterCallback(mediaProjectionCallback)
            mediaProjection?.stop()
            mediaProjection = null
            mediaProjectionManager = null
            
            Log.i(TAG, "✅ Android 15 MediaProjection管理器已销毁")
            
        } catch (e: Exception) {
            Log.e(TAG, "❌ 销毁管理器失败", e)
        }
    }
} 