package io.nexilis.service.core

import android.annotation.TargetApi
import android.app.Notification
import android.app.NotificationChannel
import android.app.NotificationManager
import android.content.Context
import android.os.Build
import androidx.annotation.StringRes
import androidx.core.app.NotificationCompat
import androidx.work.CoroutineWorker
import androidx.work.ForegroundInfo
import androidx.work.WorkManager
import androidx.work.WorkerParameters
import androidx.work.workDataOf
import io.nexilis.service.R
import io.nexilis.service.Service

class Outgoing(context: Context, parameters: WorkerParameters) :
    CoroutineWorker(context, parameters) {
    override suspend fun doWork(): Result {
        try {
            inputData.getString("data")?.let {
                Service.sendSync(it)?.let { data ->
                    return Result.success(
                        workDataOf(
                            "message_id" to data.bodies["A18"],
                            "opposite_pin" to data.bodies["A01"],
                            "status" to data.bodies["A15"]?.toInt()
                        )
                    )
                }
            }
        } catch (e: Exception) {
            Result.failure()
        }
        return Result.retry()
    }

    private val notificationManager =
        context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager

    override suspend fun getForegroundInfo(): ForegroundInfo {
        val notificationId = 112345
        return ForegroundInfo(notificationId, createNotification())
    }

    private fun getString(@StringRes id: Int) = applicationContext.getString(id)

    private fun createNotification(): Notification {
        val channelId = getString(R.string.notification_channel_id)
        val title = getString(R.string.notification_title)
        val cancel = getString(R.string.cancel_processing)
        val name = getString(R.string.channel_name)
        // This PendingIntent can be used to cancel the Worker.
        val intent = WorkManager.getInstance(applicationContext).createCancelPendingIntent(id)

        val builder = NotificationCompat.Builder(applicationContext, channelId)
            .setContentTitle(title)
            .setTicker(title)
            .setSmallIcon(applicationContext.applicationInfo.icon)
            .setOngoing(true)
            .addAction(R.drawable.baseline_cancel_24, cancel, intent)
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            createNotificationChannel(channelId, name).also {
                builder.setChannelId(it.id)
            }
        }
        return builder.build()
    }

    @TargetApi(Build.VERSION_CODES.O)
    private fun createNotificationChannel(
        channelId: String,
        name: String
    ): NotificationChannel {
        return NotificationChannel(
            channelId, name, NotificationManager.IMPORTANCE_LOW
        ).also { channel ->
            notificationManager.createNotificationChannel(channel)
        }
    }
}