package dev.privacyllc.period.notifications

import dev.privacyllc.period.core.data.CycleRepository
import dev.privacyllc.period.core.datastore.UserPreferencesRepository
import dev.privacyllc.period.core.notifications.PeriodNotifier
import java.time.Clock
import java.time.LocalDate
import javax.inject.Inject
import javax.inject.Singleton

/**
 * Turns a notification action into the same thing the in-app button does.
 *
 * That equivalence is the whole point, and it is easy to get wrong: two paths
 * into one piece of state usually means two slightly different pieces of state.
 * Answering "Not yet" from a lock screen must produce exactly the
 * `NotYetObservation` the Today screen's button produces, or the forecast the
 * user sees when they open the app will not match the one the notification was
 * about.
 *
 * §31 also asks for sensible handling before details are exposed: tapping an
 * action opens the app, which is behind whatever device lock the user has. The
 * action itself records the answer; nothing is displayed until the app is
 * actually in front of them.
 */
@Singleton
class NotificationActionHandler @Inject constructor(
    private val repository: CycleRepository,
    private val preferences: UserPreferencesRepository,
    private val clock: Clock,
) {

    /** Returns true when the action was recognised and applied. */
    suspend fun handle(action: String?): Boolean {
        val today = LocalDate.now(clock)
        return when (action) {
            PeriodNotifier.ACTION_STARTED -> {
                repository.confirmPeriodStart(today)
                // The question is answered, so the app is willing to ask again
                // next cycle rather than staying permanently quiet.
                preferences.resetCheckIns()
                true
            }

            PeriodNotifier.ACTION_NOT_YET -> {
                // Exactly what the Today screen's "Not yet" does — same call,
                // same censoring observation, same re-conditioned forecast.
                repository.recordNotYet(today)
                true
            }

            else -> false
        }
    }
}
