package app.closer.domain.model

import java.time.LocalDate

/**
 * A weekly progress snapshot shown to a couple on their chosen recap day.
 *
 * All answer/game/challenge data is summarized by count and category only.
 * No decrypted answer text is stored here unless it has already been revealed to both partners.
 *
 * @property weekStart the local date of the first day included in the recap (inclusive)
 * @property weekEnd the local date of the last day included in the recap (inclusive), normally the recap day
 * @property questionsAnswered number of questions answered by either partner during the week
 * @property revealsOpened number of reveals opened by the couple during the week
 * @property gamesCompleted number of games completed during the week
 * @property challengeProgressDays number of unique challenge days completed by both partners this week
 * @property favoriteCategory the category ID the couple engaged with most, or null if no data
 * @property favoriteCategoryDisplay user-facing name for the favorite category; safe to show in-app
 * @property dateIdeaSaved true if a date idea was saved during the week
 * @property memoryCapsuleCreated true if a memory capsule was created during the week
 * @property memoryCapsuleUnlocked true if a sealed memory capsule became unlocked during the week
 * @property suggestedNextPack the pack recommended for next week, based on favorite or least-used category
 * @property strongestRhythmCopy human-readable summary of the couple's most active time pattern
 * @property bodyCopy formatted recap body matching the design spec
 * @property ctaCopy call-to-action text, e.g. "Choose next week's pack"
 */
data class WeeklyRecap(
    val weekStart: LocalDate,
    val weekEnd: LocalDate,
    val questionsAnswered: Int = 0,
    val revealsOpened: Int = 0,
    val gamesCompleted: Int = 0,
    val challengeProgressDays: Int = 0,
    val favoriteCategory: String? = null,
    val favoriteCategoryDisplay: String? = null,
    val dateIdeaSaved: Boolean = false,
    val memoryCapsuleCreated: Boolean = false,
    val memoryCapsuleUnlocked: Boolean = false,
    val suggestedNextPack: QuestionPack? = null,
    val strongestRhythmCopy: String? = null,
    val bodyCopy: String = "",
    val ctaCopy: String = "Choose next week's pack"
)

/**
 * Raw input for generating a weekly recap.
 *
 * Lists contain events for both partners where relevant. [weekStart] and [weekEnd] are local dates;
 * callers must convert timestamps to local dates using the couple's timezone before invoking the generator.
 */
data class WeeklyRecapInput(
    val weekStart: LocalDate,
    val weekEnd: LocalDate,
    val answers: List<WeeklyRecapAnswer> = emptyList(),
    val reveals: List<WeeklyRecapReveal> = emptyList(),
    val gamesCompleted: List<WeeklyRecapGame> = emptyList(),
    val challengeProgress: List<WeeklyRecapChallengeDay> = emptyList(),
    val dateIdeasSaved: List<WeeklyRecapDateIdea> = emptyList(),
    val capsules: List<WeeklyRecapCapsule> = emptyList(),
    val availablePacks: List<QuestionPack> = emptyList(),
    val categoryTitles: Map<String, String> = emptyMap()
)

/**
 * A single answer event for recap counting.
 *
 * @property userId the answering partner
 * @property questionId the question answered
 * @property categoryId question category for favorite-category tally
 * @property localDate local calendar day the answer was submitted
 * @property isRevealed true if both partners have already revealed this answer
 * @property hasText true if the answer contains written text
 */
data class WeeklyRecapAnswer(
    val userId: String,
    val questionId: String,
    val categoryId: String?,
    val localDate: LocalDate,
    val isRevealed: Boolean = false,
    val hasText: Boolean = false
)

/**
 * A reveal event opened by the couple during the week.
 */
data class WeeklyRecapReveal(
    val localDate: LocalDate
)

/**
 * A completed game event.
 */
data class WeeklyRecapGame(
    val localDate: LocalDate,
    val gameType: String? = null
)

/**
 * A single completed challenge day.
 */
data class WeeklyRecapChallengeDay(
    val challengeId: String,
    val day: Int,
    val localDate: LocalDate
)

/**
 * A saved date idea event.
 */
data class WeeklyRecapDateIdea(
    val localDate: LocalDate
)

/**
 * A memory capsule event.
 *
 * @property localDate local calendar day the capsule was created or unlocked
 * @property isUnlock true if this represents an unlock event; false for creation
 */
data class WeeklyRecapCapsule(
    val localDate: LocalDate,
    val isUnlock: Boolean = false
)
