package com.base.scanqr.fcm.notification

import android.content.Context
import com.base.scanqr.BuildConfig
import com.base.scanqr.bean.NotificationSendBean
import com.base.scanqr.bean.NotificationSendBean.Companion.ACTION_ID_SCAN
import com.base.scanqr.bean.NotificationSendBean.Companion.POPUP_WHERE_LOCK
import com.base.scanqr.bean.NotificationSendBean.Companion.POPUP_WHERE_TIMBER
import com.base.scanqr.bean.config.PopupConfigBean.Companion.popupConfigBean
import com.base.scanqr.helper.EventUtils
import com.base.scanqr.utils.AppPreferences
import com.base.scanqr.utils.KotlinExt.currentDate
import com.base.scanqr.utils.LogEx
import com.base.scanqr.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.atomic.AtomicBoolean

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

    private val TAG = "NotificationManager"

    private var sendBeanBlockingQueue = ArrayBlockingQueue<NotificationSendBean>(10)

    private val looper_actionId = listOf(
        ACTION_ID_SCAN,
    )

    private var actionIdList = arrayListOf<String>()
    private fun getNextActionId(): String {
        if (actionIdList.isEmpty()) {
            actionIdList.addAll(looper_actionId)
        }
        val next = actionIdList[0]
        actionIdList.removeAt(0)
        if (BuildConfig.DEBUG) {
//            return NOTIFICATION_ACTION_WEATHER
        }
        return next
    }

    fun submitSendBean(bean: NotificationSendBean) {
        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) {
                val bean = sendBeanBlockingQueue.take()

                //测试哪些位置触发
                if (BuildConfig.DEBUG) {
                    if (!testWhere.contains(bean.where)) continue
                }

                LogEx.logDebug(TAG, "sendNotificationIfCan where=${bean.where}")
                EventUtils.event("Notification_Popup_Start", "where=${bean.where}")

                if (!isUnLimit) {
                    //总的限制条件
                    if (!canSendNotification(bean.context)) continue

                    //当条推送是否可以推送
                    if (!bean.canSend.invoke()) continue
                }

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

                //上报通知
                EventUtils.event("Notification_Popup", "where=${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_Error", "status=${popupConfigBean.popupStatus}")
            LogEx.logDebug("canSendNotification", "status")
            if (BuildConfig.DEBUG) {
                MainScope().launch(Dispatchers.Main) {
                    context.toast("配置关闭推送")
                }
            }
            return false
        }

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

        //判断是否在时间区域
        val start = popupConfigBean.popupStart
        val end = popupConfigBean.popupEnd
        val calendar = Calendar.getInstance()
        val currentHour = calendar.get(Calendar.HOUR_OF_DAY)
        if (currentHour !in start until end) {
            LogEx.logDebug(TAG, "start=$start end=$end currentHour=$currentHour")
            EventUtils.event("Notification_Error", "start=$start end=$end currentHour=$currentHour")
            return false
        }

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

    /**
     * 只测某些类型
     */
    private var testWhere = listOf(
        POPUP_WHERE_LOCK
    )
}