package com.bestitguys.glancetest

import android.annotation.SuppressLint
import android.app.Application
import android.appwidget.AppWidgetManager
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.os.Process
import android.util.Log
import androidx.core.app.TaskStackBuilder
import androidx.work.*
import com.bestitguys.glancetest.model.DataItem
import com.bestitguys.glancetest.widgets.FullWidgetProvider
import com.bestitguys.glancetest.work.WidgetWorker
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch

class App: Application() {

    companion object{

        @SuppressLint("StaticFieldLeak")
        lateinit var context: Context
        private val workManager by lazy { WorkManager.getInstance(context) }
        var data = generateData()

        private fun generateData(): List<DataItem>{
            val list = mutableListOf<DataItem>()
            repeat(100){
                list.add(
                    DataItem(
                        id = it,
                        title = "Item $it",
                        subtitle = "description $it",
                        timestamp = System.currentTimeMillis() - it*100000
                    )
                )
            }
            return list
        }

        fun getData(ids: Set<String>) = data.filter { ids.contains("${it.id}") }

        fun enqueueUniqueWork(
            requestBuilder: OneTimeWorkRequest.Builder,
            tag: String
        ){
            // sometimes this may fail on older OS versions if Expedited quota is reached
            try{
                workManager.enqueueUniqueWork(
                    tag, ExistingWorkPolicy.APPEND_OR_REPLACE,
                    requestBuilder
                        .setExpedited(OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST)
                        .build()
                )
            }catch (t: Throwable){
                // try running it non-expedited
                try{
                    workManager.enqueueUniqueWork(
                        tag, ExistingWorkPolicy.APPEND_OR_REPLACE,
                        requestBuilder.build()
                    )
                }catch (tt: Throwable){
                    Log.d("***", tt.localizedMessage ?: "WorkManager FAILED")
                }
            }
        }

        fun launchActivity(mClass: Class<*>?, noBackStack: Boolean = false) {
            if (noBackStack) {
                TaskStackBuilder.create(context)
                    .addParentStack(MainActivity::class.java)
                    .addNextIntent(Intent(context, mClass))
                    .startActivities()
            } else {
                TaskStackBuilder.create(context)
                    .addParentStack(MainActivity::class.java)
                    .addNextIntent(Intent(context, MainActivity::class.java))
                    .addNextIntent(Intent(context, mClass))
                    .startActivities()
            }
        }

        fun updateWidgets(){
            val intent = Intent(context, FullWidgetProvider::class.java)
            intent.action = AppWidgetManager.ACTION_APPWIDGET_UPDATE
            val ids = AppWidgetManager.getInstance(context)
                .getAppWidgetIds(ComponentName(context, FullWidgetProvider::class.java))
            intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, ids)
            context.sendBroadcast(intent)

            try {
                val awm = AppWidgetManager.getInstance(context)
                awm.getAppWidgetIds(
                    ComponentName(
                        context,
                        FullWidgetProvider::class.java
                    )
                )?.let {
                    if(it.isNotEmpty()) {
//                        val i = Intent(App.ACT_UPDATE_WIDGETS)
//                        i.putExtra(App.EXTRA_WIDGET_IDS, widgetIds_all_pic)
//                        i.putExtra(App.EXTRA_WIDGET_TYPE, ServiceWidgetUpdate.TYPE_ALL_PIC)
//                        ServiceWidgetUpdate.enqueueWork(mContext, i)
                    }
                }
            } catch (e: Exception) {
                Log.d("***", "WIDGETS failed")
            }
        }


        /*
         * Creates a thread, sets it to lower priority, and runs the Runnable code in it
         */
        fun runInBackgroundThread(r: Runnable?) {
            if (r != null) {
                val t = Thread(r)
                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND)
                t.start()
            }
        }
    }

    override fun onCreate() {
        super.onCreate()
        context = this
        updateWidgets()

        runInBackgroundThread{
            repeat(10){
                try {
                    Thread.sleep(1000)
                } catch (ignored: InterruptedException) {
                }
                val workRequest = OneTimeWorkRequestBuilder<WidgetWorker>()
                enqueueUniqueWork(workRequest, WidgetWorker.TAG)
            }
        }
    }
}