package de.wechselbild.wallpaper

import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.app.Service
import android.content.Context
import android.content.Intent
import android.os.Build
import android.os.Handler
import android.os.IBinder
import android.os.Looper
import androidx.core.app.NotificationCompat
import androidx.core.content.ContextCompat
import java.util.concurrent.Executors

class WallpaperRotationService : Service() {
  private val worker = Executors.newSingleThreadExecutor()
  private val handler = Handler(Looper.getMainLooper())
  private val rotate = object : Runnable {
    override fun run() {
      if (!WallpaperStore.enabled(this@WallpaperRotationService)) {
        stopSelf()
        return
      }
      worker.execute {
        if (WallpaperScheduler.claimIfDue(this@WallpaperRotationService)) try {
          WallpaperStore.applyNext(this@WallpaperRotationService)
        } finally {
          WallpaperScheduler.scheduleNext(this@WallpaperRotationService)
        }
        handler.post { scheduleLocalTimer() }
      }
    }
  }

  override fun onCreate() {
    super.onCreate()
    runningService = this
    createChannel()
    val launch = packageManager.getLaunchIntentForPackage(packageName)
    val pending = PendingIntent.getActivity(this, 0, launch, PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT)
    val notification = NotificationCompat.Builder(this, CHANNEL)
      .setSmallIcon(android.R.drawable.ic_menu_gallery)
      .setContentTitle(getString(R.string.wallpaper_service_title))
      .setContentText(getString(R.string.wallpaper_service_text))
      .setOngoing(true).setSilent(true).setContentIntent(pending).build()
    startForeground(NOTIFICATION_ID, notification)
    WallpaperScheduler.ensureScheduled(this)
    scheduleLocalTimer()
  }

  override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
    if (!WallpaperStore.enabled(this)) {
      stopSelf()
      return START_NOT_STICKY
    }
    WallpaperScheduler.ensureScheduled(this)
    scheduleLocalTimer()
    return START_STICKY
  }
  override fun onBind(intent: Intent?): IBinder? = null

  override fun onDestroy() {
    handler.removeCallbacks(rotate)
    worker.shutdown()
    if (runningService === this) runningService = null
    super.onDestroy()
  }

  private fun scheduleLocalTimer() {
    handler.removeCallbacks(rotate)
    if (WallpaperStore.enabled(this)) {
      handler.postDelayed(rotate, WallpaperScheduler.remainingDelay(this))
    }
  }

  private fun createChannel() {
    if (Build.VERSION.SDK_INT >= 26) {
      val channel = NotificationChannel(CHANNEL, getString(R.string.wallpaper_channel_name), NotificationManager.IMPORTANCE_LOW)
      getSystemService(NotificationManager::class.java).createNotificationChannel(channel)
    }
  }

  companion object {
    private const val CHANNEL = "wechselbild_rotation"
    private const val NOTIFICATION_ID = 4217
    @Volatile private var runningService: WallpaperRotationService? = null

    fun rescheduleRunningService() {
      val service = runningService ?: return
      service.handler.post { service.scheduleLocalTimer() }
    }
    fun start(context: Context) {
      WallpaperScheduler.ensureScheduled(context)
      ContextCompat.startForegroundService(context, Intent(context, WallpaperRotationService::class.java))
    }
    fun restart(context: Context) {
      WallpaperScheduler.scheduleNext(context)
      start(context)
    }
    fun stop(context: Context) {
      WallpaperScheduler.cancel(context)
      context.stopService(Intent(context, WallpaperRotationService::class.java))
    }
  }
}
