package com.tt.honeyDue.widget import kotlinx.datetime.DateTimeUnit import kotlinx.datetime.LocalDateTime import kotlinx.datetime.TimeZone import kotlinx.datetime.plus import kotlinx.datetime.toInstant import kotlinx.datetime.toLocalDateTime /** * Pure-logic schedule for widget refresh cadence. Mirrors the iOS-parity * split from the P3 parity plan: * * - 06:00 (inclusive) .. 23:00 (exclusive) local → refresh every 30 minutes * - 23:00 (inclusive) .. 06:00 (exclusive) local → refresh every 120 minutes * * iOS ([BackgroundTaskManager.swift]) uses a random 12am–4am overnight * BGAppRefreshTask window rather than a fixed cadence, because iOS * `BGTaskScheduler` is coalesced by the system. Android's WorkManager runs * user-defined intervals, so this file encodes the ios-parity cadence the * plan specifies. The split 30/120 preserves the core intent: frequent * while awake, sparse while the user is asleep. */ object WidgetRefreshSchedule { private const val DAY_START_HOUR_INCLUSIVE = 6 // 06:00 local private const val DAY_END_HOUR_EXCLUSIVE = 23 // 23:00 local const val DAY_INTERVAL_MINUTES: Long = 30L const val NIGHT_INTERVAL_MINUTES: Long = 120L /** * Returns the refresh interval (in minutes) for a wall-clock time. * * Hour bands: * - [06:00, 23:00) → [DAY_INTERVAL_MINUTES] (30) * - [23:00, 06:00) → [NIGHT_INTERVAL_MINUTES] (120) */ fun intervalMinutes(at: LocalDateTime): Long { val hour = at.hour return if (hour in DAY_START_HOUR_INCLUSIVE until DAY_END_HOUR_EXCLUSIVE) { DAY_INTERVAL_MINUTES } else { NIGHT_INTERVAL_MINUTES } } /** * Returns `now + intervalMinutes(now)` as a [LocalDateTime]. * * Arithmetic is performed through [TimeZone.UTC] to avoid ambiguity * around DST transitions in the local zone — the absolute minute offset * is what WorkManager's `setInitialDelay` consumes, so the returned * wall-clock value is for display/testing only. */ fun nextRefreshTime(now: LocalDateTime): LocalDateTime { val interval = intervalMinutes(now) val instant = now.toInstant(TimeZone.UTC) val next = instant.plus(interval, DateTimeUnit.MINUTE) return next.toLocalDateTime(TimeZone.UTC) } }