package com.base.appzxhy.business.push.notification

import android.content.Context
import com.base.appzxhy.BuildConfig
import com.base.appzxhy.MyApplication
import com.base.appzxhy.bean.FeatureBean.Companion.BATTERY_INFO
import com.base.appzxhy.bean.FeatureBean.Companion.JUNK_CLEAN
import com.base.appzxhy.bean.FeatureBean.Companion.LARGE_FILE_CLEAN
import com.base.appzxhy.bean.FeatureBean.Companion.PHOTO_COMPRESSION
import com.base.appzxhy.bean.FeatureBean.Companion.SCREENSHOT_CLEAN
import com.base.appzxhy.bean.FeatureBean.Companion.SIMILAR_PHOTOS
import com.base.appzxhy.bean.push.NotificationSendBean
import com.base.appzxhy.bean.push.NotificationSendBean.Companion.POPUP_WHERE_WORK_MANAGER
import com.base.appzxhy.bean.config.PopupConfigBean.Companion.popupConfigBean
import com.base.appzxhy.bean.push.NotificationSendBean.Companion.POPUP_WHERE_ALARM
import com.base.appzxhy.bean.push.NotificationSendBean.Companion.POPUP_WHERE_LOCK
import com.base.appzxhy.bean.push.NotificationSendBean.Companion.POPUP_WHERE_TIMER
import com.base.appzxhy.business.helper.EventUtils
import com.base.appzxhy.utils.AppPreferences
import com.base.appzxhy.utils.KotlinExt.currentDate
import com.base.appzxhy.utils.LogEx
import com.base.appzxhy.utils.ToastUtils.toast
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.async
import kotlinx.coroutines.isActive
import kotlinx.coroutines.launch
import java.util.Calendar
import java.util.concurrent.ArrayBlockingQueue
import java.util.concurrent.TimeUnit
import java.util.concurrent.atomic.AtomicBoolean

/**
 * 发送通知的管理类,方便测试限制条件
 */
object MyNotificationManager {

    private val TAG = "MyNotificationManager"

    private var sendBeanBlockingQueue = ArrayBlockingQueue<NotificationSendBean>(10)

    fun submitSendBean(bean: NotificationSendBean) {
        //测试哪些位置触发
        if (BuildConfig.DEBUG) {
            if (!testWhere.contains(bean.where)) return
        }

        LogEx.logDebug(TAG, "sendNotificationIfCan where=${bean.where}")
        if (!isUnLimit) {
            //应用在前台不推
            if (MyApplication.PAUSED_VALUE == 1 && !popupConfigBean.popupForegroundCanPush) {
                LogEx.logDebug(TAG, "app Foreground")
                return
            }
            //总的限制条件
            if (!canSendNotification(bean.context)) {
                return
            }

            //其他条推送是否可以推送
            if (!bean.canSend.invoke()) {
                return
            }
        }

        if (bean.actionId.isEmpty()) {
            val actionId = getNextActionId()
            bean.actionId = actionId
        }
        try {
            sendBeanBlockingQueue.put(bean)
        } catch (e: Exception) {
            EventUtils.event("Notification_Error", "submitSendBean Exception")
            LogEx.logDebug("canSendNotification", "submitSendBean Exception")
        }
    }

    private var isStartSendQueue = AtomicBoolean(false)

    private var isUnLimit: Boolean = if (BuildConfig.DEBUG) false else false

    fun startNotificationQueue() {
        if (isStartSendQueue.get()) return
        isStartSendQueue.set(true)

        MainScope().launch(Dispatchers.IO) {
            while (isActive) {
                // 尝试从队列中获取元素，最多等待 5 秒
                var bean = sendBeanBlockingQueue.poll(5, TimeUnit.SECONDS)
//                Log.e(TAG, "bean=$bean")

                if (bean != null) {

//                EventUtils.event("Notification_Popup_Start", "where=${bean.where}")

                    //提前准备数据
                    when (bean.actionId) {

                    }

                    bean = async(Dispatchers.Main) {
                        NotificationUiUtil.setNotification(bean)
                    }.await()

                    LogEx.logDebug(TAG, "sendNotificationCan where=${bean.where} actionId=${bean.actionId}")
                    //上报通知
                    EventUtils.event("Notification_Popup_${bean.where}", "actionId=${bean.actionId}")
                    //当天次数加一
                    dayPopupCount += 1
                    //推送时间
                    lastPopupTime = System.currentTimeMillis()

                    //这条推送回调
                    bean.sendSuccess?.invoke()

                    async(Dispatchers.Main) {
                        //发送悬停
                        NotificationHoverUtils.sendHoverNotification(bean)
                    }.await()
                }
            }
            isStartSendQueue.set(false)
        }
    }

    //当天推送次数
    private var dayPopupCount = 0
        get() {
            return AppPreferences.getInstance().getInt("dayPopupCount_${currentDate()}", field)
        }
        set(value) {
            field = value
            AppPreferences.getInstance().put("dayPopupCount_${currentDate()}", value, true)
        }

    //上次推送时间
    private var lastPopupTime = 0L
        get() {
            return AppPreferences.getInstance().getLong("lastPopupTime", field)
        }
        set(value) {
            field = value
            AppPreferences.getInstance().put("lastPopupTime", value, true)
        }

    /**
     * 总的限制条件
     */
    private fun canSendNotification(context: Context): Boolean {

        //是否开启推送
        if (!popupConfigBean.popupStatus) {
            EventUtils.event("Notification_Limit", "status=${popupConfigBean.popupStatus}")
            LogEx.logDebug(TAG, "Notification_Limit status=${popupConfigBean.popupStatus}")
            if (BuildConfig.DEBUG) {
                MainScope().launch(Dispatchers.Main) {
                    context.toast("配置关闭推送")
                }
            }
            return false
        }

        //当天推送次数
        val popupCount = popupConfigBean.popupCount
        if (dayPopupCount > popupCount) {
            LogEx.logDebug(TAG, "Notification_Limit dayPopupCount=$dayPopupCount popupCount=$popupCount")
            EventUtils.event("Notification_Limit", "dayPopupCount=$dayPopupCount popupCount=$popupCount")
            return false
        }

        //判断是否在限制时间区域
        val calendar = Calendar.getInstance()
        val currentHour = calendar.get(Calendar.HOUR_OF_DAY)
        val limitRangeTime = popupConfigBean.popupLimitRangeTime
        if (limitRangeTime.contains(currentHour)) {
            LogEx.logDebug(TAG, "Notification_Limit currentHour=$currentHour popupLimitRangeTime=$limitRangeTime")
            EventUtils.event("Notification_Limit", "currentHour=$currentHour popupLimitRangeTime=$limitRangeTime")
            return false
        }

        //总时间间隔,单位分钟
        val interval = popupConfigBean.popupInterval
        val passedTime = System.currentTimeMillis() - lastPopupTime
        if (passedTime < interval * 60 * 1000L) {
//            EventUtils.event("Notification_Limit", "interval=$interval passedTime=$passedTime")
            LogEx.logDebug(TAG, "Notification_Limit interval=$interval passedTime=$passedTime")
            return false
        }
        return true
    }

    /**
     * 值测某些类型
     */
    private var testWhere = listOf(
        POPUP_WHERE_TIMER,
        POPUP_WHERE_LOCK,
        POPUP_WHERE_ALARM,
        POPUP_WHERE_WORK_MANAGER
    )
    private val looper_actionId = listOf(
//        ACTION_ID_TEST,
        JUNK_CLEAN,
        BATTERY_INFO,
        SCREENSHOT_CLEAN,
        LARGE_FILE_CLEAN,
        PHOTO_COMPRESSION,
        SIMILAR_PHOTOS,
    )
    private var actionIdList = arrayListOf<String>()
    private fun getNextActionId(): String {

//        if (BuildConfig.DEBUG) {
//            return JUNK_CLEAN
//        }

        if (actionIdList.isEmpty()) {
            actionIdList.addAll(looper_actionId)
        }
        val next = actionIdList[0]
        actionIdList.removeAt(0)
        return next
    }
}