package no.naiv.meddetsamme.alarm import android.content.BroadcastReceiver import android.content.Context import android.content.Intent import java.time.LocalDate import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import no.naiv.meddetsamme.data.MedDatabase import no.naiv.meddetsamme.domain.ScheduleEngine import no.naiv.meddetsamme.notify.Notifications /** * Daily derived-state check: low stock (inventory ÷ scheduled rate) and * prescription renewal (rx expiry, independent of stock — decision #9). * One digest notification, not one per med. */ class SupplyCheckReceiver : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { val pending = goAsync() CoroutineScope(Dispatchers.IO).launch { try { check(context) } finally { AlarmScheduler(context).armSupplyCheck() // chain the next daily check pending.finish() } } } private suspend fun check(context: Context) { val db = MedDatabase.get(context) val today = LocalDate.now() val lines = mutableListOf() for (med in db.medicationDao().getActive()) { val doseTimes = db.doseTimeDao().getForMed(med.id) val rate = ScheduleEngine.dailyConsumption(doseTimes) if (ScheduleEngine.needsRefill(med.inventoryUnits, rate, med.lowStockLeadDays)) { val days = ScheduleEngine.daysOfSupply(med.inventoryUnits, rate) lines += "${med.name}: lager for ${days?.toInt() ?: 0} dager" } if (ScheduleEngine.needsRenewal(med.rxExpiryEpochDay, today)) { val expired = med.rxExpiryEpochDay!! < today.toEpochDay() lines += if (expired) "${med.name}: resept utløpt" else "${med.name}: resept må fornyes" } } if (lines.isNotEmpty()) { Notifications.post( context, Notifications.SUPPLY_NOTIFICATION_ID, Notifications.buildSupplyNotification(context, lines), ) } } }