package com.remax.notification.timing

import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.os.Handler
import android.os.Looper
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleObserver
import androidx.lifecycle.OnLifecycleEvent
import androidx.lifecycle.ProcessLifecycleOwner
import androidx.work.PeriodicWorkRequestBuilder
import androidx.work.WorkManager
import androidx.work.workDataOf
import com.ama.core.architecture.util.DateUtil
import com.ama.core.architecture.util.SpUtil
import com.blankj.utilcode.util.Utils
import com.remax.base.report.DataReportManager
import com.remax.notification.TaskStateNewBieFirstWithDraw2
import com.remax.notification.controller.NotificationTriggerController
import com.remax.notification.check.NotificationCheckController
import com.remax.notification.newUtil.NotificationDatas
import com.remax.notification.newUtil.NotificationDatas.TIME_GAP_FOR_NOTIFY_INTERVAL
import com.remax.notification.newUtil.NotificationDatas.NOTI_TYPE_BG_WITHDRAW
import com.remax.notification.newUtil.NotificationRecorder
import com.remax.notification.newUtil.NotificationUtil
import com.remax.notification.utils.NotiLogger
import com.remax.notification.utils.FCMTopicManager
import com.remax.notification.service.FCMService
import com.remax.notification.service.NotificationKeepAliveServiceManager
import com.remax.notification.worker.NotificationKeepAliveWorker
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import java.util.concurrent.TimeUnit
import java.util.concurrent.atomic.AtomicBoolean

/**
 * 通知时机控制器
 * 监听锁屏和app切到后台事件，在合适的时机触发通知
 */
class NotificationTimingController private constructor() : LifecycleObserver {

    companion object {
        private const val TAG = "NotificationTimingController"
        
        @Volatile
        private var INSTANCE: NotificationTimingController? = null
        
        fun getInstance(): NotificationTimingController {
            return INSTANCE ?: synchronized(this) {
                INSTANCE ?: NotificationTimingController().also { INSTANCE = it }
            }
        }
    }

    private val scope = CoroutineScope(SupervisorJob() + Dispatchers.Main)
    private val isInitialized = AtomicBoolean(false)
    private val isAppInForeground = AtomicBoolean(false)  // 添加前台状态标识位
    private var context: Context? = null
    private var screenReceiver: ScreenReceiver? = null

    /**
     * 初始化通知时机控制器
     * @param context 上下文
     */
    fun initialize(context: Context) {
        if (isInitialized.getAndSet(true)) {
            NotiLogger.d("通知时机控制器已经初始化")
            return
        }

        this.context = context.applicationContext
        NotiLogger.d("通知时机控制器初始化开始")

        // 注册锁屏监听
        registerScreenReceiver()
        
        // 注册应用生命周期监听
        registerAppLifecycleObserver()

        // 启动 WorkManager 保活
        startWorkManagerKeepAlive()
        
        // 订阅 FCM 主题
        subscribeFCMTopics()
        
        // 初始化 FCM 服务
        FCMService.initialize()
        
        // 获取并记录 FCM 令牌
        FCMTopicManager.getFCMToken { token ->
            if (token != null) {
                NotiLogger.d("FCM 令牌获取成功，长度: ${token.length}")
            } else {
                NotiLogger.w("FCM 令牌获取失败")
            }
        }
        
        // 记录 FCM 订阅状态
        FCMTopicManager.logSubscriptionStatus()

        NotiLogger.d("通知时机控制器初始化完成")
    }

    /**
     * 订阅 FCM 主题
     */
    private fun subscribeFCMTopics() {
        try {
            NotiLogger.d("开始订阅 FCM 主题")
            FCMTopicManager.subscribeCommonTopic()
            NotiLogger.d("FCM 主题订阅完成")
        } catch (e: Exception) {
            NotiLogger.e("订阅 FCM 主题失败", e)
        }
    }
    
    /**
     * 启动 WorkManager 保活
     */
    private fun startWorkManagerKeepAlive() {
        try {
            // 延迟初始化 WorkManager，确保应用完全启动
            Handler(Looper.getMainLooper()).postDelayed({
                try {
                    val workManager = WorkManager.getInstance(context!!)
                    
                    // 取消现有的周期性保活工作
                    workManager.cancelUniqueWork("notification_keep_alive")

                    // 创建周期性保活工作（每15分钟执行一次）
                    val periodicWorkRequest = PeriodicWorkRequestBuilder<NotificationKeepAliveWorker>(
                        15, TimeUnit.MINUTES
                    ).setInputData(workDataOf("type" to "periodic_keep_alive"))
                        .build()
                    
                    // 提交周期性工作请求
                    workManager.enqueueUniquePeriodicWork(
                        "notification_keep_alive",
                        androidx.work.ExistingPeriodicWorkPolicy.REPLACE,
                        periodicWorkRequest
                    )
                    
                    NotiLogger.d("WorkManager 周期性保活已启动（每15分钟执行一次）")
                } catch (e: Exception) {
                    NotiLogger.e("启动 WorkManager 保活失败", e)
                }
            }, 1000) // 延迟1秒执行
        } catch (e: Exception) {
            NotiLogger.e("启动 WorkManager 保活失败", e)
        }
    }

    /**
     * 注册锁屏广播接收器
     */
    private fun registerScreenReceiver() {
        try {
            screenReceiver = ScreenReceiver()
            val filter = IntentFilter().apply {
                addAction(Intent.ACTION_SCREEN_OFF)
                addAction(Intent.ACTION_SCREEN_ON)
                addAction(Intent.ACTION_USER_PRESENT)
            }
            context?.registerReceiver(screenReceiver, filter)
            NotiLogger.d("锁屏监听器注册成功")
        } catch (e: Exception) {
            NotiLogger.e("注册锁屏监听器失败", e)
        }
    }

    /**
     * 注册应用生命周期观察者
     */
    private fun registerAppLifecycleObserver() {
        try {
            ProcessLifecycleOwner.get().lifecycle.addObserver(this)
            NotiLogger.d("应用生命周期监听器注册成功")
        } catch (e: Exception) {
            NotiLogger.e("注册应用生命周期监听器失败", e)
        }
    }

    /**
     * 应用切到后台
     */
    @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
    fun onAppBackground() {
        isAppInForeground.set(false)
        NotiLogger.d("应用切到后台")
        triggerNotificationIfAllowed(NotificationCheckController.NotificationType.BACKGROUND)
    }

    /**
     * 应用切到前台
     */
    @OnLifecycleEvent(Lifecycle.Event.ON_START)
    fun onAppForeground() {
        isAppInForeground.set(true)
        NotiLogger.d("应用切到前台")
        NotificationTriggerController.stopRepeatNotification()
        Utils.getApp().let {
            NotificationKeepAliveServiceManager.startKeepAliveService(it)
        }

    }

    /**
     * 检查应用是否在前台
     * @return 是否在前台
     */
    fun isAppInForeground(): Boolean {
        return isAppInForeground.get()
    }

    /**
     * 锁屏广播接收器
     */
    inner class ScreenReceiver : BroadcastReceiver() {
        override fun onReceive(context: Context?, intent: Intent?) {
            when (intent?.action) {
                Intent.ACTION_SCREEN_OFF -> {
                    NotiLogger.d("屏幕关闭")
                    NotificationTriggerController.stopRepeatNotification()
                }
                Intent.ACTION_SCREEN_ON -> {
                    NotiLogger.d("屏幕点亮")
                    context?.let {
                        NotificationKeepAliveServiceManager.startKeepAliveService(context)
                    }
                }
                Intent.ACTION_USER_PRESENT -> {
                    handleUnlock()
                }
            }
        }
    }

    /**
     * 处理解锁事件
     */
    private fun handleUnlock() {
        NotiLogger.d("用户解锁屏幕")
        triggerNotificationIfAllowed(NotificationCheckController.NotificationType.UNLOCK)
    }


    /**
     * 释放资源
     */
    fun release() {
        try {
            screenReceiver?.let { receiver ->
                context?.unregisterReceiver(receiver)
                screenReceiver = null
            }

            ProcessLifecycleOwner.get().lifecycle.removeObserver(this)

            isInitialized.set(false)
            context = null

            NotiLogger.d("通知时机控制器已释放")
        } catch (e: Exception) {
            NotiLogger.e("释放通知时机控制器失败", e)
        }
    }

    /**
     * 通用通知触发方法
     * @param type 通知类型
     */
    fun triggerNotificationIfAllowed(type: NotificationCheckController.NotificationType) {
        val description = when (type) {
            NotificationCheckController.NotificationType.UNLOCK -> "解锁通知"
            NotificationCheckController.NotificationType.BACKGROUND -> "后台通知"
            NotificationCheckController.NotificationType.KEEPALIVE -> "保活通知"
            NotificationCheckController.NotificationType.FCM -> "FCM推送通知"
            NotificationCheckController.NotificationType.RESIDENT -> "常驻通知"
            NotificationCheckController.NotificationType.FIXTIMEPOINT -> "固定时间点通知"
            NotificationCheckController.NotificationType.APPINSTALL -> "APP安装卸载"
            NotificationCheckController.NotificationType.CHARGE -> "手机充电"
        }
        DataReportManager.reportData("Notific_Pull", mapOf("topic" to "localPush"))


        
        /*// 检查是否可以触发通知，并获取具体的拦截原因
        val checkResult = NotificationCheckController.getInstance().canTriggerNotificationWithReason(type)
        if (*//*!checkResult.first*//*false) {
            val blockReason = checkResult.second
            val reasonString = blockReason?.reason ?: "unknown"
            val reasonDescription = blockReason?.description ?: "未知原因"
            
            NotiLogger.d("${description}检查未通过，跳过触发 - 原因: ${reasonDescription}")
            DataReportManager.reportData("Notific_Show_Fail", mapOf(
                "reason" to "app_inner_${type.string}_${reasonString}",
            ))
            return
        }

        NotiLogger.d("触发${description}")
        NotificationTriggerController.triggerGeneralNotification(type){
            NotificationCheckController.getInstance().recordNotificationTrigger(type)
            NotificationCheckController.getInstance().incrementNotificationCount()
        }*/

        when (type) {
            NotificationCheckController.NotificationType.KEEPALIVE -> {

            }

            NotificationCheckController.NotificationType.FCM -> {

            }

            NotificationCheckController.NotificationType.RESIDENT -> {

            }

            NotificationCheckController.NotificationType.FIXTIMEPOINT -> {
                showNotifyRandom(NotificationCheckController.NotificationType.FIXTIMEPOINT.string, listOf(2,3,4,6,7,8))
            }

            NotificationCheckController.NotificationType.APPINSTALL -> {
                showNotifyRandom(NotificationCheckController.NotificationType.APPINSTALL.string, listOf(3,5,7,9,11))
            }

            NotificationCheckController.NotificationType.CHARGE -> {
                showNotifyRandom(NotificationCheckController.NotificationType.CHARGE.string, listOf(1,3,5,7,9,11))
            }

            NotificationCheckController.NotificationType.UNLOCK -> {
                showNotifyRandom(NotificationCheckController.NotificationType.UNLOCK.string, listOf(2,4,6,8,10,11))
            }

            NotificationCheckController.NotificationType.BACKGROUND -> {
                showNotifyWithdraw(NotificationCheckController.NotificationType.BACKGROUND.string)
                //showNotifyResident()
            }
        }


    }




    private fun showNotifyWithdraw(notifyType:String) {
        if (System.currentTimeMillis() - NotificationRecorder.getLastNotifyShowTime(notifyType) >= TIME_GAP_FOR_NOTIFY_INTERVAL) {
            val hasClaimedSmallCash = SpUtil.instance().getObject<TaskStateNewBieFirstWithDraw2>(SpUtil.KEY_NEWBIE_FIRST_WITHDRAW)?.hasClaimReward
            NotificationDatas.getConfigForType(NOTI_TYPE_BG_WITHDRAW)?.let {
                it.content = String.format(it.content, if (hasClaimedSmallCash == null || !hasClaimedSmallCash) 0.1 else 50)
                //NotificationUtil.getInstance().showHeadsUpNotification(it)
                NotificationUtil.getInstance().showExpandableNotification(it)

                NotificationRecorder.saveLastNotifyShowTime(notifyType, DateUtil.getCurTimeMs())
            }
        }
    }

    private fun showNotifyRandom(notifyType:String, randomList: List<Int>) {
        if (System.currentTimeMillis() - NotificationRecorder.getLastNotifyShowTime(notifyType) >= TIME_GAP_FOR_NOTIFY_INTERVAL) {
            NotificationUtil.getInstance().showBasicNotification(NotificationDatas.getRandomConfig(notifyType, randomList))
            NotificationRecorder.saveLastNotifyShowTime(notifyType, DateUtil.getCurTimeMs())
        }
    }


}
