package com.ponzischeme89.memby.ui.player

import android.content.Context
import androidx.work.CoroutineWorker
import androidx.work.Data
import androidx.work.ExistingWorkPolicy
import androidx.work.OneTimeWorkRequestBuilder
import androidx.work.WorkManager
import androidx.work.WorkerParameters
import com.ponzischeme89.memby.ServiceLocator
import com.ponzischeme89.memby.data.PlaybackSession

/**
 * A persisted final check-in. WorkManager keeps this request across process death, so
 * Back, task removal and background process eviction all converge on the same Emby stop.
 */
class PlaybackStopWorker(
    appContext: Context,
    params: WorkerParameters,
) : CoroutineWorker(appContext, params) {
    override suspend fun doWork(): Result {
        ServiceLocator.init(applicationContext)
        val itemId = inputData.getString(ITEM_ID).orEmpty()
        if (itemId.isBlank()) return Result.failure()
        val session = PlaybackSession(
            itemId = itemId,
            mediaSourceId = inputData.getString(MEDIA_SOURCE_ID).orEmpty().ifBlank { itemId },
            playSessionId = inputData.getString(PLAY_SESSION_ID).orEmpty(),
            playMethod = inputData.getString(PLAY_METHOD).orEmpty().ifBlank { "DirectPlay" },
        )
        return runCatching {
            ServiceLocator.repository.reportPlaybackStopped(
                session,
                inputData.getLong(POSITION_MS, 0L),
            )
        }.fold(
            onSuccess = { Result.success() },
            onFailure = { if (runAttemptCount < MAX_RETRIES) Result.retry() else Result.failure() },
        )
    }

    companion object {
        private const val ITEM_ID = "item_id"
        private const val MEDIA_SOURCE_ID = "media_source_id"
        private const val PLAY_SESSION_ID = "play_session_id"
        private const val PLAY_METHOD = "play_method"
        private const val POSITION_MS = "position_ms"
        private const val MAX_RETRIES = 5

        fun enqueue(context: Context, session: PlaybackSession, positionMs: Long) {
            val data = Data.Builder()
                .putString(ITEM_ID, session.itemId)
                .putString(MEDIA_SOURCE_ID, session.mediaSourceId)
                .putString(PLAY_SESSION_ID, session.playSessionId)
                .putString(PLAY_METHOD, session.playMethod)
                .putLong(POSITION_MS, positionMs.coerceAtLeast(0L))
                .build()
            val request = OneTimeWorkRequestBuilder<PlaybackStopWorker>()
                .setInputData(data)
                .build()
            val key = session.playSessionId.ifBlank { session.itemId }
            WorkManager.getInstance(context.applicationContext).enqueueUniqueWork(
                "emby-playback-stop-$key",
                ExistingWorkPolicy.REPLACE,
                request,
            )
        }
    }
}
