package com.zxhyis.toolss.notification.task

import android.content.Context
import androidx.work.BackoffPolicy
import androidx.work.Data
import androidx.work.ExistingPeriodicWorkPolicy
import androidx.work.PeriodicWorkRequest
import androidx.work.WorkInfo
import androidx.work.WorkManager
import com.google.gson.Gson
import com.zxhyis.toolss.ad.bean.EventParams
import com.zxhyis.toolss.ad.bean.PushManagement
import com.zxhyis.toolss.logic.LogEx
import java.util.concurrent.ExecutionException
import java.util.concurrent.Executors
import java.util.concurrent.ScheduledExecutorService
import java.util.concurrent.TimeUnit

class PeriodicTaskScheduler private constructor() {

    private val TAG = "PeriodicTaskScheduler"
    private val scheduler: ScheduledExecutorService = Executors.newSingleThreadScheduledExecutor()
    private var pushManagement: PushManagement? = null
    private var eventParams: EventParams? = null
    var isRunning = false


    fun start(context: Context) {
        startTimer()
        startPeriodicTask(context)
    }


    fun setPushParams(pushManagement: PushManagement): PeriodicTaskScheduler {
        this.pushManagement = pushManagement
//        TIMER_INTERVAL_MINUTES = pushManagement.loop_interval
        return this
    }

    fun setEventParam(eventParams: EventParams?): PeriodicTaskScheduler {
        this.eventParams = eventParams
        return this
    }

    /**
     * 轮训通知
     */
    private fun startTimer() {
        LogEx.logDebug(TAG, "startTimer is isRunning=$isRunning")
        if (isRunning) {
            return
        }
        scheduler.scheduleAtFixedRate(NotificationTask(eventParams), 0, TIMER_INTERVAL_MINUTES.toLong(), TimeUnit.SECONDS)
        isRunning = true
    }

    /**
     * 周期性启动轮训 PeriodicWorkRequest
     */
    private fun startPeriodicTask(context: Context) {
        val isWorkRunning = isNotificationWorkerRunning(context)
        LogEx.logDebug(TAG, "startPeriodicTask isWorkRunning=$isWorkRunning")
        if (isWorkRunning) {
            LogEx.logDebug(TAG, "startPeriodicTask is Running")
            return
        }
        val inputData = Data.Builder()
            .putString("param", Gson().toJson(eventParams))
            .build()
        val periodicWorkRequest: PeriodicWorkRequest =
            PeriodicWorkRequest.Builder(NotificationWorker::class.java, CHECK_INTERVAL_MINUTES, TimeUnit.MINUTES)
                .setBackoffCriteria(BackoffPolicy.LINEAR, PeriodicWorkRequest.MIN_BACKOFF_MILLIS, TimeUnit.MILLISECONDS)
                .addTag(WORKER_TAG)
                .setInputData(inputData)
                .build()
        WorkManager.getInstance(context).enqueueUniquePeriodicWork(WORKER_TAG, ExistingPeriodicWorkPolicy.REPLACE, periodicWorkRequest)
    }

    fun stop() {
        scheduler.shutdown()
        isRunning = false
    }

    companion object {
        var instance: PeriodicTaskScheduler? = null
            get() {
                if (field == null) {
                    synchronized(PeriodicTaskScheduler::class.java) {
                        if (field == null) {
                            field = PeriodicTaskScheduler()
                        }
                    }
                }
                return field
            }
            private set

        private const val WORKER_TAG = "Notification_super_timer"
        private const val CHECK_INTERVAL_MINUTES = 15L
        private var TIMER_INTERVAL_MINUTES = 30
        private fun isNotificationWorkerRunning(context: Context): Boolean {
            val workManager = WorkManager.getInstance(context)
            try {
                val workInfos = workManager.getWorkInfosByTag(WORKER_TAG).get()
                for (workInfo in workInfos) {
                    if (workInfo.state == WorkInfo.State.RUNNING || workInfo.state == WorkInfo.State.ENQUEUED) {
                        return true
                    }
                }
            } catch (e: ExecutionException) {
                e.printStackTrace()
            } catch (e: InterruptedException) {
                e.printStackTrace()
            }
            return false
        }
    }
}
