package com.a2i.forwarder.core

import android.content.Context
import androidx.work.Constraints
import androidx.work.CoroutineWorker
import androidx.work.ExistingPeriodicWorkPolicy
import androidx.work.NetworkType
import androidx.work.PeriodicWorkRequestBuilder
import androidx.work.WorkManager
import androidx.work.WorkerParameters
import com.a2i.forwarder.A2iApp
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.json.Json
import java.util.concurrent.TimeUnit

class RetryWorker(ctx: Context, params: WorkerParameters) : CoroutineWorker(ctx, params) {

    override suspend fun doWork(): Result {
        val app = A2iApp.instance
        val store = app.logStore
        val settings = app.settings
        val list = store.pending.value
        if (list.isEmpty()) return Result.success()

        var allOk = true
        val json = Json { ignoreUnknownKeys = true }
        for (p in list) {
            val server = settings.servers.value.firstOrNull { it.id == p.serverId }
                ?: settings.currentServer.value
                ?: continue
            if (server.deviceKey.isBlank()) { allOk = false; continue }
            val msg = runCatching { json.decodeFromString<com.a2i.forwarder.model.BarkMessage>(p.messageJson) }.getOrNull() ?: continue
            val r = BarkClient(server).push(msg)
            if (r.isSuccess) store.removePending(p.id) else allOk = false
        }
        return if (allOk) Result.success() else Result.retry()
    }

    companion object {
        private const val NAME = "a2i_retry"

        fun schedule(context: Context) {
            val req = PeriodicWorkRequestBuilder<RetryWorker>(15, TimeUnit.MINUTES)
                .setConstraints(
                    Constraints.Builder().setRequiredNetworkType(NetworkType.CONNECTED).build()
                )
                .build()
            WorkManager.getInstance(context)
                .enqueueUniquePeriodicWork(NAME, ExistingPeriodicWorkPolicy.UPDATE, req)
        }
    }
}
