package app.closer.domain.model

import java.time.LocalDate

/**
 * Represents the current state of an active couple challenge from the current user's perspective.
 *
 * Challenge states form a small shared ritual: not started → started today → waiting for partner
 * → both completed today → (optional missed day) → challenge complete.
 *
 * This model is intentionally plain so it can be computed deterministically and consumed by the
 * UI layer without business logic leakage.
 *
 * @property state the high-level challenge state
 * @property title challenge title (safe to display)
 * @property emoji challenge emoji
 * @property totalDays total length of the challenge, normally 7
 * @property currentDay the day the current user is currently on, 1-based, capped at [totalDays]
 * @property myCompletedDays days the current user has marked complete
 * @property partnerCompletedDays days the partner has marked complete
 * @property jointCompletedDays days both partners have completed
 * @property isComplete true when the challenge has been finished
 * @property copy user-facing copy describing the current state
 * @property cta user-facing call-to-action copy, or null when no action is available
 * @property badge small celebratory indicator shown when the challenge is complete, or null
 * @property canAdvance true when the user can mark today's step complete
 * @property missedDate the local date of a detected missed day, if any
 */
data class ChallengeState(
    val state: ChallengeStatus = ChallengeStatus.NOT_STARTED,
    val title: String = "",
    val emoji: String = "",
    val totalDays: Int = 7,
    val currentDay: Int = 1,
    val myCompletedDays: List<Int> = emptyList(),
    val partnerCompletedDays: List<Int> = emptyList(),
    val jointCompletedDays: List<Int> = emptyList(),
    val isComplete: Boolean = false,
    val copy: String = "",
    val cta: String? = null,
    val badge: String? = null,
    val canAdvance: Boolean = false,
    val missedDate: LocalDate? = null
)

/**
 * High-level challenge statuses used by the UI and priority engine.
 *
 * Ordered roughly by lifecycle:
 * 1. [NOT_STARTED] — no active challenge or challenge selected but not yet started
 * 2. [STARTED_TODAY] — challenge active, user marked today's step complete, partner has not
 * 3. [WAITING_FOR_PARTNER] — challenge active, user did their part today, waiting on partner
 * 4. [BOTH_COMPLETED_TODAY] — challenge active, both partners completed today's step
 * 5. [DAY_MISSED] — challenge active, neither partner completed the expected day by the end of the day
 * 6. [CHALLENGE_COMPLETE] — all days jointly completed or explicitly finished
 */
enum class ChallengeStatus {
    NOT_STARTED,
    STARTED_TODAY,
    WAITING_FOR_PARTNER,
    BOTH_COMPLETED_TODAY,
    DAY_MISSED,
    CHALLENGE_COMPLETE
}

/**
 * Raw input for computing a [ChallengeState].
 *
 * All date handling is done with [LocalDate] so the state machine stays pure and testable.
 * Callers (e.g. the ViewModel) must convert timestamps to the couple's local calendar day.
 *
 * @property challenge the challenge definition
 * @property progress raw completion progress from Firestore/Room
 * @property today the local date to evaluate against
 * @property breakOnMissedDay if true, a missed day marks the whole challenge as [DAY_MISSED]
 *   and prevents further advancement until handled by the caller. Default is false: missed
 *   days are surfaced but do not break the ritual.
 */
data class ChallengeStateInput(
    val challenge: ConnectionChallenge,
    val progress: ChallengeProgressState,
    val today: LocalDate,
    val breakOnMissedDay: Boolean = false
)
