//! Static seed list for Challenge mode + helpers.
//!
//! Challenge mode walks a fixed sequence of hard-but-winnable seeds. The
//! player advances by winning a deal in `GameMode::Challenge`. The
//! `challenge_index` cursor is stored per-player in `PlayerProgress`.
//!
//! Seeds wrap modulo `CHALLENGE_SEEDS.len()` so a sufficiently dedicated
//! player never runs out of challenges.

/// Curated Challenge-mode seeds. Order is stable across versions; add new
/// seeds at the end.
pub const CHALLENGE_SEEDS: &[u64] = &[
    // Round 1 (original 5)
    0xDEAD_BEEF_CAFE_F00D,
    0xC0DE_FACE_8BAD_F00D,
    0xFEE1_DEAD_DEAD_BEEF,
    0xBAAD_F00D_BAAD_F00D,
    0x1337_C0DE_4242_BABE,
    // Round 2
    0xACED_CAFE_B0BA_1234,
    0x5A1D_F00D_BEEF_CAFE,
    0xF01D_BABE_CAFE_BEEF,
    0xD00D_1E42_ABCD_EF01,
    0x7EA5_ED01_2345_6789,
    // Round 3
    0xC1A5_51C0_F00D_CAFE,
    0xBA5E_BA11_DEAD_BEEF,
    0xFACE_B00C_C0DE_1010,
    0x5EED_CAFE_5EED_CAFE,
    0xABBA_ABBA_CAFE_BABE,
    // Round 4
    0x1234_5678_9ABC_DEF0,
    0xFEDC_BA98_7654_3210,
    0x0011_2233_4455_6677,
    0x8899_AABB_CCDD_EEFF,
    0x1111_2222_3333_4444,
    // Round 5
    0x5555_6666_7777_8888,
    0x9999_AAAA_BBBB_CCCC,
    0xDDDD_EEEE_FFFF_0000,
    0x0101_0101_0101_0101,
    0xA1B2_C3D4_E5F6_0718,
    // Generated by solitaire_assetgen::gen_seeds (start=0xCAFEBABE00000000, count=75, date=2026-05-09)
    0xCAFE_BABE_0000_0000,
    0xCAFE_BABE_0000_0002,
    0xCAFE_BABE_0000_0004,
    0xCAFE_BABE_0000_0008,
    0xCAFE_BABE_0000_000B,
    0xCAFE_BABE_0000_000D,
    0xCAFE_BABE_0000_000E,
    0xCAFE_BABE_0000_0010,
    0xCAFE_BABE_0000_0011,
    0xCAFE_BABE_0000_0014,
    0xCAFE_BABE_0000_0016,
    0xCAFE_BABE_0000_0019,
    0xCAFE_BABE_0000_001A,
    0xCAFE_BABE_0000_001F,
    0xCAFE_BABE_0000_0020,
    0xCAFE_BABE_0000_0021,
    0xCAFE_BABE_0000_0024,
    0xCAFE_BABE_0000_0025,
    0xCAFE_BABE_0000_0027,
    0xCAFE_BABE_0000_002B,
    0xCAFE_BABE_0000_002D,
    0xCAFE_BABE_0000_0030,
    0xCAFE_BABE_0000_0034,
    0xCAFE_BABE_0000_0036,
    0xCAFE_BABE_0000_003A,
    0xCAFE_BABE_0000_003B,
    0xCAFE_BABE_0000_003D,
    0xCAFE_BABE_0000_0042,
    0xCAFE_BABE_0000_0043,
    0xCAFE_BABE_0000_0044,
    0xCAFE_BABE_0000_004C,
    0xCAFE_BABE_0000_004D,
    0xCAFE_BABE_0000_004F,
    0xCAFE_BABE_0000_0050,
    0xCAFE_BABE_0000_0051,
    0xCAFE_BABE_0000_0054,
    0xCAFE_BABE_0000_0055,
    0xCAFE_BABE_0000_0056,
    0xCAFE_BABE_0000_0059,
    0xCAFE_BABE_0000_005B,
    0xCAFE_BABE_0000_005C,
    0xCAFE_BABE_0000_005E,
    0xCAFE_BABE_0000_0060,
    0xCAFE_BABE_0000_0062,
    0xCAFE_BABE_0000_0064,
    0xCAFE_BABE_0000_0067,
    0xCAFE_BABE_0000_0069,
    0xCAFE_BABE_0000_006A,
    0xCAFE_BABE_0000_006B,
    0xCAFE_BABE_0000_006C,
    0xCAFE_BABE_0000_006D,
    0xCAFE_BABE_0000_006E,
    0xCAFE_BABE_0000_006F,
    0xCAFE_BABE_0000_0072,
    0xCAFE_BABE_0000_0073,
    0xCAFE_BABE_0000_0074,
    0xCAFE_BABE_0000_0079,
    0xCAFE_BABE_0000_007A,
    0xCAFE_BABE_0000_007D,
    0xCAFE_BABE_0000_007E,
    0xCAFE_BABE_0000_007F,
    0xCAFE_BABE_0000_0082,
    0xCAFE_BABE_0000_0083,
    0xCAFE_BABE_0000_0084,
    0xCAFE_BABE_0000_0085,
    0xCAFE_BABE_0000_0089,
    0xCAFE_BABE_0000_008A,
    0xCAFE_BABE_0000_008D,
    0xCAFE_BABE_0000_008E,
    0xCAFE_BABE_0000_0090,
    0xCAFE_BABE_0000_0094,
    0xCAFE_BABE_0000_0095,
    0xCAFE_BABE_0000_0098,
    0xCAFE_BABE_0000_0099,
    0xCAFE_BABE_0000_009F,
];

/// Resolve a `challenge_index` to its corresponding seed, wrapping when
/// the index exceeds the seed-list length. Returns `None` if the seed list
/// is empty (defensive — `CHALLENGE_SEEDS` is non-empty by construction).
pub fn challenge_seed_for(index: u32) -> Option<u64> {
    if CHALLENGE_SEEDS.is_empty() {
        return None;
    }
    Some(CHALLENGE_SEEDS[(index as usize) % CHALLENGE_SEEDS.len()])
}

/// Total number of currently-defined challenges. Useful for displaying
/// "Challenge {n + 1} of {total}" in UI.
pub fn challenge_count() -> u32 {
    CHALLENGE_SEEDS.len() as u32
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn challenge_seed_for_0_is_first_seed() {
        assert_eq!(challenge_seed_for(0), Some(CHALLENGE_SEEDS[0]));
    }

    #[test]
    fn challenge_seed_wraps_past_end() {
        let len = CHALLENGE_SEEDS.len() as u32;
        assert_eq!(
            challenge_seed_for(len),
            Some(CHALLENGE_SEEDS[0]),
            "wraps to seed 0 when index == len"
        );
        assert_eq!(
            challenge_seed_for(len + 2),
            Some(CHALLENGE_SEEDS[2]),
            "wraps modulo len"
        );
    }

    #[test]
    fn all_challenge_seeds_are_unique() {
        let mut seeds: Vec<u64> = CHALLENGE_SEEDS.to_vec();
        seeds.sort();
        let len_before = seeds.len();
        seeds.dedup();
        assert_eq!(seeds.len(), len_before);
    }
}
