package com.tt.honeyDue.widget

import android.content.Context
import androidx.work.ExistingWorkPolicy
import androidx.work.OneTimeWorkRequestBuilder
import androidx.work.OutOfQuotaPolicy
import androidx.work.WorkManager
import kotlinx.datetime.Clock
import kotlinx.datetime.TimeZone
import kotlinx.datetime.toLocalDateTime
import java.util.concurrent.TimeUnit

/**
 * Scheduler for the widget-refresh background work. Thin wrapper over
 * [WorkManager] that enqueues a [WidgetRefreshWorker] with the cadence
 * defined by [WidgetRefreshSchedule].
 *
 * We use a chained one-time-work pattern rather than `PeriodicWorkRequest`
 * because:
 *  - `PeriodicWorkRequest` has a 15-minute floor which is fine, but more
 *    importantly can't *vary* its cadence between runs.
 *  - The iOS-parity spec needs 30-min during the day and 120-min overnight
 *    — so each run computes the next interval based on the local clock
 *    and enqueues the next one-time request.
 *
 * On [schedulePeriodic], the worker is enqueued with an initial delay of
 * `intervalMinutes(now)`. On successful completion [WidgetRefreshWorker]
 * calls [schedulePeriodic] again to chain the next wake.
 */
object WidgetUpdateManager {

    /** Unique name for the periodic (chained) refresh queue. */
    const val UNIQUE_WORK_NAME: String = "widget_refresh_periodic"

    /** Unique name for user- / app-triggered forced refreshes. */
    const val FORCE_REFRESH_WORK_NAME: String = "widget_refresh_force"

    /**
     * Schedule the next periodic refresh. Delay = [WidgetRefreshSchedule.intervalMinutes]
     * evaluated against the current local-zone clock. Existing work under
     * [UNIQUE_WORK_NAME] is replaced — the new interval always wins.
     */
    fun schedulePeriodic(context: Context) {
        val now = Clock.System.now().toLocalDateTime(TimeZone.currentSystemDefault())
        val delayMinutes = WidgetRefreshSchedule.intervalMinutes(now)

        val request = OneTimeWorkRequestBuilder<WidgetRefreshWorker>()
            .setInitialDelay(delayMinutes, TimeUnit.MINUTES)
            .addTag(TAG)
            .build()

        WorkManager.getInstance(context.applicationContext)
            .enqueueUniqueWork(UNIQUE_WORK_NAME, ExistingWorkPolicy.REPLACE, request)
    }

    /**
     * Force an immediate refresh. Runs as an expedited worker so the OS
     * treats it as a foreground-ish job (best-effort — may be denied
     * quota, in which case it falls back to a regular one-time enqueue).
     */
    fun forceRefresh(context: Context) {
        val request = OneTimeWorkRequestBuilder<WidgetRefreshWorker>()
            .setExpedited(OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST)
            .addTag(TAG)
            .build()

        WorkManager.getInstance(context.applicationContext)
            .enqueueUniqueWork(FORCE_REFRESH_WORK_NAME, ExistingWorkPolicy.REPLACE, request)
    }

    /**
     * Cancel any pending/chained periodic refresh. Does not affect
     * in-flight forced refreshes — call [cancel] from a logout flow to
     * stop the scheduler wholesale, or clear both queues explicitly.
     */
    fun cancel(context: Context) {
        val wm = WorkManager.getInstance(context.applicationContext)
        wm.cancelUniqueWork(UNIQUE_WORK_NAME)
        wm.cancelUniqueWork(FORCE_REFRESH_WORK_NAME)
    }

    private const val TAG = "widget_refresh"
}
