package com.jttools.datacontrol.data import java.time.LocalDate /** * Réglages persistés de l'application, avec leurs valeurs par défaut. */ data class AppSettings( val controlEnabled: Boolean = false, val planLimitMo: Long = 5000L, val planPriceEuro: Double = 19.99, val overagePricePerMoEuro: Double = 0.01, val planStartDateEpochDay: Long = LocalDate.now().toEpochDay(), val autoResetEnabled: Boolean = true, val cutoffIntervalMinutes: Int = 15, val baselineMobileBytesAtReset: Long = 0L, val whitelistedPackages: Set = emptySet(), val showSystemApps: Boolean = false, val passwordHash: String? = null, val passwordSalt: String? = null ) { val planStartDate: LocalDate get() = LocalDate.ofEpochDay(planStartDateEpochDay) /** Un mot de passe de verrouillage protège la désactivation du contrôle et l'accès aux réglages. */ val hasPassword: Boolean get() = !passwordHash.isNullOrEmpty() /** Prochaine date de réinitialisation automatique (anniversaire mensuel du début de forfait). */ fun nextAutoResetDate(): LocalDate { var next = planStartDate.plusMonths(1) val today = LocalDate.now() while (!next.isAfter(today)) { next = next.plusMonths(1) } return next } } /** État calculé de la consommation, dérivé des réglages + de la mesure de données réelle. */ data class UsageState( val consumedMo: Long, val planLimitMo: Long, val overageMo: Long, val isOverPlan: Boolean, val estimatedTotalPriceEuro: Double ) { val percentOfPlan: Float get() = if (planLimitMo <= 0) 0f else (consumedMo.toFloat() / planLimitMo.toFloat()).coerceAtLeast(0f) } enum class DataState { OK, // sous le forfait WARNING, // proche du forfait (>= 80%) OVERRUN_FILTER, // dépassé, liste blanche seule active OVERRUN_CUT, // dépassé, coupure totale cyclique en cours WIFI // Wi-Fi actif, aucun filtrage appliqué }