package app.closer.analytics

/**
 * Enumeration of all retention-focused analytics event types.
 *
 * These events measure feature engagement, not content. They intentionally carry only
 * metadata — never answer text, prompts, or decrypted content.
 */
enum class RetentionEventType {
    DAILY_QUESTION_ASSIGNED,
    DAILY_QUESTION_VIEWED,
    DAILY_QUESTION_ANSWERED,
    PARTNER_ANSWERED,
    REVEAL_OPENED,
    REVEAL_COMPLETED,
    FOLLOW_UP_QUESTION_OPENED,
    GAME_STARTED,
    GAME_COMPLETED,
    CHALLENGE_STARTED,
    CHALLENGE_DAY_COMPLETED,
    CHALLENGE_COMPLETED,
    DATE_IDEA_SAVED,
    DATE_REMINDER_OPENED,
    WEEKLY_RECAP_OPENED,
    MEMORY_CAPSULE_CREATED,
    MEMORY_CAPSULE_UNLOCKED,
    PUSH_NOTIFICATION_SENT,
    PUSH_NOTIFICATION_OPENED,
    DAILY_MODE_RESOLVED,
    DAILY_TINY_ACTION_VIEWED,
    DAILY_TINY_ACTION_SAVED,
    COUPLE_LORE_SAVED,
}

/**
 * Sealed hierarchy of retention events.
 *
 * Every event carries only safe metadata:
 *  - featureName: the feature surface the event belongs to
 *  - eventType: one of [RetentionEventType]
 *  - categoryId: an opaque category identifier, if relevant
 *  - coupleIdHash: SHA-256 hash of the couple ID, never the raw couple ID
 *  - timestamp: epoch millis when the event was created
 *
 * No answer text, prompt text, or decrypted content may ever be added to these events.
 */
sealed class RetentionEvent(
    open val featureName: String,
    open val eventType: RetentionEventType,
    open val categoryId: String?,
    open val coupleIdHash: String?,
    open val timestamp: Long = System.currentTimeMillis(),
) {
    data class DailyQuestionAssigned(
        override val categoryId: String? = null,
        override val coupleIdHash: String? = null,
        override val timestamp: Long = System.currentTimeMillis(),
    ) : RetentionEvent(
        featureName = "daily_question",
        eventType = RetentionEventType.DAILY_QUESTION_ASSIGNED,
        categoryId = categoryId,
        coupleIdHash = coupleIdHash,
        timestamp = timestamp,
    )

    data class DailyQuestionViewed(
        override val categoryId: String? = null,
        override val coupleIdHash: String? = null,
        override val timestamp: Long = System.currentTimeMillis(),
    ) : RetentionEvent(
        featureName = "daily_question",
        eventType = RetentionEventType.DAILY_QUESTION_VIEWED,
        categoryId = categoryId,
        coupleIdHash = coupleIdHash,
        timestamp = timestamp,
    )

    data class DailyQuestionAnswered(
        override val categoryId: String? = null,
        override val coupleIdHash: String? = null,
        override val timestamp: Long = System.currentTimeMillis(),
    ) : RetentionEvent(
        featureName = "daily_question",
        eventType = RetentionEventType.DAILY_QUESTION_ANSWERED,
        categoryId = categoryId,
        coupleIdHash = coupleIdHash,
        timestamp = timestamp,
    )

    data class PartnerAnswered(
        override val categoryId: String? = null,
        override val coupleIdHash: String? = null,
        override val timestamp: Long = System.currentTimeMillis(),
    ) : RetentionEvent(
        featureName = "daily_question",
        eventType = RetentionEventType.PARTNER_ANSWERED,
        categoryId = categoryId,
        coupleIdHash = coupleIdHash,
        timestamp = timestamp,
    )

    data class RevealOpened(
        override val categoryId: String? = null,
        override val coupleIdHash: String? = null,
        override val timestamp: Long = System.currentTimeMillis(),
    ) : RetentionEvent(
        featureName = "reveal",
        eventType = RetentionEventType.REVEAL_OPENED,
        categoryId = categoryId,
        coupleIdHash = coupleIdHash,
        timestamp = timestamp,
    )

    data class RevealCompleted(
        override val categoryId: String? = null,
        override val coupleIdHash: String? = null,
        override val timestamp: Long = System.currentTimeMillis(),
    ) : RetentionEvent(
        featureName = "reveal",
        eventType = RetentionEventType.REVEAL_COMPLETED,
        categoryId = categoryId,
        coupleIdHash = coupleIdHash,
        timestamp = timestamp,
    )

    data class FollowUpQuestionOpened(
        override val categoryId: String? = null,
        override val coupleIdHash: String? = null,
        override val timestamp: Long = System.currentTimeMillis(),
    ) : RetentionEvent(
        featureName = "follow_up",
        eventType = RetentionEventType.FOLLOW_UP_QUESTION_OPENED,
        categoryId = categoryId,
        coupleIdHash = coupleIdHash,
        timestamp = timestamp,
    )

    data class GameStarted(
        override val categoryId: String? = null,
        override val coupleIdHash: String? = null,
        override val timestamp: Long = System.currentTimeMillis(),
    ) : RetentionEvent(
        featureName = "game",
        eventType = RetentionEventType.GAME_STARTED,
        categoryId = categoryId,
        coupleIdHash = coupleIdHash,
        timestamp = timestamp,
    )

    data class GameCompleted(
        override val categoryId: String? = null,
        override val coupleIdHash: String? = null,
        override val timestamp: Long = System.currentTimeMillis(),
    ) : RetentionEvent(
        featureName = "game",
        eventType = RetentionEventType.GAME_COMPLETED,
        categoryId = categoryId,
        coupleIdHash = coupleIdHash,
        timestamp = timestamp,
    )

    data class ChallengeStarted(
        override val categoryId: String? = null,
        override val coupleIdHash: String? = null,
        override val timestamp: Long = System.currentTimeMillis(),
    ) : RetentionEvent(
        featureName = "challenge",
        eventType = RetentionEventType.CHALLENGE_STARTED,
        categoryId = categoryId,
        coupleIdHash = coupleIdHash,
        timestamp = timestamp,
    )

    data class ChallengeDayCompleted(
        override val categoryId: String? = null,
        override val coupleIdHash: String? = null,
        override val timestamp: Long = System.currentTimeMillis(),
    ) : RetentionEvent(
        featureName = "challenge",
        eventType = RetentionEventType.CHALLENGE_DAY_COMPLETED,
        categoryId = categoryId,
        coupleIdHash = coupleIdHash,
        timestamp = timestamp,
    )

    data class ChallengeCompleted(
        override val categoryId: String? = null,
        override val coupleIdHash: String? = null,
        override val timestamp: Long = System.currentTimeMillis(),
    ) : RetentionEvent(
        featureName = "challenge",
        eventType = RetentionEventType.CHALLENGE_COMPLETED,
        categoryId = categoryId,
        coupleIdHash = coupleIdHash,
        timestamp = timestamp,
    )

    data class DateIdeaSaved(
        override val categoryId: String? = null,
        override val coupleIdHash: String? = null,
        override val timestamp: Long = System.currentTimeMillis(),
    ) : RetentionEvent(
        featureName = "date_idea",
        eventType = RetentionEventType.DATE_IDEA_SAVED,
        categoryId = categoryId,
        coupleIdHash = coupleIdHash,
        timestamp = timestamp,
    )

    data class DateReminderOpened(
        override val categoryId: String? = null,
        override val coupleIdHash: String? = null,
        override val timestamp: Long = System.currentTimeMillis(),
    ) : RetentionEvent(
        featureName = "date_idea",
        eventType = RetentionEventType.DATE_REMINDER_OPENED,
        categoryId = categoryId,
        coupleIdHash = coupleIdHash,
        timestamp = timestamp,
    )

    data class WeeklyRecapOpened(
        override val categoryId: String? = null,
        override val coupleIdHash: String? = null,
        override val timestamp: Long = System.currentTimeMillis(),
    ) : RetentionEvent(
        featureName = "weekly_recap",
        eventType = RetentionEventType.WEEKLY_RECAP_OPENED,
        categoryId = categoryId,
        coupleIdHash = coupleIdHash,
        timestamp = timestamp,
    )

    data class MemoryCapsuleCreated(
        override val categoryId: String? = null,
        override val coupleIdHash: String? = null,
        override val timestamp: Long = System.currentTimeMillis(),
    ) : RetentionEvent(
        featureName = "memory_capsule",
        eventType = RetentionEventType.MEMORY_CAPSULE_CREATED,
        categoryId = categoryId,
        coupleIdHash = coupleIdHash,
        timestamp = timestamp,
    )

    data class MemoryCapsuleUnlocked(
        override val categoryId: String? = null,
        override val coupleIdHash: String? = null,
        override val timestamp: Long = System.currentTimeMillis(),
    ) : RetentionEvent(
        featureName = "memory_capsule",
        eventType = RetentionEventType.MEMORY_CAPSULE_UNLOCKED,
        categoryId = categoryId,
        coupleIdHash = coupleIdHash,
        timestamp = timestamp,
    )

    data class PushNotificationSent(
        override val categoryId: String? = null,
        override val coupleIdHash: String? = null,
        override val timestamp: Long = System.currentTimeMillis(),
    ) : RetentionEvent(
        featureName = "push_notification",
        eventType = RetentionEventType.PUSH_NOTIFICATION_SENT,
        categoryId = categoryId,
        coupleIdHash = coupleIdHash,
        timestamp = timestamp,
    )

    data class PushNotificationOpened(
        override val categoryId: String? = null,
        override val coupleIdHash: String? = null,
        override val timestamp: Long = System.currentTimeMillis(),
    ) : RetentionEvent(
        featureName = "push_notification",
        eventType = RetentionEventType.PUSH_NOTIFICATION_OPENED,
        categoryId = categoryId,
        coupleIdHash = coupleIdHash,
        timestamp = timestamp,
    )

    data class DailyModeResolved(
        override val categoryId: String? = null,
        override val coupleIdHash: String? = null,
        override val timestamp: Long = System.currentTimeMillis(),
    ) : RetentionEvent(
        featureName = "daily_question",
        eventType = RetentionEventType.DAILY_MODE_RESOLVED,
        categoryId = categoryId,
        coupleIdHash = coupleIdHash,
        timestamp = timestamp,
    )

    data class DailyTinyActionViewed(
        override val categoryId: String? = null,
        override val coupleIdHash: String? = null,
        override val timestamp: Long = System.currentTimeMillis(),
    ) : RetentionEvent(
        featureName = "daily_question",
        eventType = RetentionEventType.DAILY_TINY_ACTION_VIEWED,
        categoryId = categoryId,
        coupleIdHash = coupleIdHash,
        timestamp = timestamp,
    )

    data class DailyTinyActionSaved(
        override val categoryId: String? = null,
        override val coupleIdHash: String? = null,
        override val timestamp: Long = System.currentTimeMillis(),
    ) : RetentionEvent(
        featureName = "daily_question",
        eventType = RetentionEventType.DAILY_TINY_ACTION_SAVED,
        categoryId = categoryId,
        coupleIdHash = coupleIdHash,
        timestamp = timestamp,
    )

    data class CoupleLoreSaved(
        override val categoryId: String? = null,
        override val coupleIdHash: String? = null,
        override val timestamp: Long = System.currentTimeMillis(),
    ) : RetentionEvent(
        featureName = "couple_lore",
        eventType = RetentionEventType.COUPLE_LORE_SAVED,
        categoryId = categoryId,
        coupleIdHash = coupleIdHash,
        timestamp = timestamp,
    )
}
