import { describe, it, expect } from "vitest"
import {
  INITIAL_PROGRESS,
  calculateCorrectAnswer,
  calculateIncorrectAnswer,
  Difficulty,
  selectCardsForSession,
  generateWrongAnswers,
  shuffleOptions,
  type CardProgress,
  type SelectableCard,
  type HanziOption,
} from "./sm2"

/**
 * Unit tests for SM-2 Algorithm
 *
 * Tests the spaced repetition algorithm implementation
 * following the specification exactly.
 */

describe("SM-2 Algorithm", () => {
  describe("INITIAL_PROGRESS", () => {
    it("should have correct initial values", () => {
      expect(INITIAL_PROGRESS.easeFactor).toBe(2.5)
      expect(INITIAL_PROGRESS.interval).toBe(1)
      expect(INITIAL_PROGRESS.consecutiveCorrect).toBe(0)
      expect(INITIAL_PROGRESS.incorrectCount).toBe(0)
    })
  })

  describe("calculateCorrectAnswer", () => {
    it("should set interval to 1 for first correct answer", () => {
      const progress: CardProgress = {
        ...INITIAL_PROGRESS,
      }

      const result = calculateCorrectAnswer(progress, new Date("2025-01-01"))

      expect(result.interval).toBe(1)
      expect(result.consecutiveCorrect).toBe(1)
      expect(result.easeFactor).toBe(2.6) // 2.5 + 0.1
      expect(result.nextReviewDate).toEqual(new Date("2025-01-02"))
    })

    it("should set interval to 6 for second correct answer", () => {
      const progress: CardProgress = {
        easeFactor: 2.6,
        interval: 1,
        consecutiveCorrect: 1,
        incorrectCount: 0,
        nextReviewDate: new Date("2025-01-02"),
      }

      const result = calculateCorrectAnswer(progress, new Date("2025-01-02"))

      expect(result.interval).toBe(6)
      expect(result.consecutiveCorrect).toBe(2)
      expect(result.easeFactor).toBe(2.7) // 2.6 + 0.1
      expect(result.nextReviewDate).toEqual(new Date("2025-01-08"))
    })

    it("should multiply interval by easeFactor for third+ correct answer", () => {
      const progress: CardProgress = {
        easeFactor: 2.7,
        interval: 6,
        consecutiveCorrect: 2,
        incorrectCount: 0,
        nextReviewDate: new Date("2025-01-08"),
      }

      const result = calculateCorrectAnswer(progress, new Date("2025-01-08"))

      // 6 * 2.7 = 16.2, rounded = 16
      expect(result.interval).toBe(16)
      expect(result.consecutiveCorrect).toBe(3)
      expect(result.easeFactor).toBeCloseTo(2.8) // 2.7 + 0.1
      expect(result.nextReviewDate).toEqual(new Date("2025-01-24"))
    })

    it("should continue increasing ease factor with each correct answer", () => {
      const progress: CardProgress = {
        easeFactor: 3.0,
        interval: 50,
        consecutiveCorrect: 5,
        incorrectCount: 2,
        nextReviewDate: new Date("2025-02-20"),
      }

      const result = calculateCorrectAnswer(progress, new Date("2025-02-20"))

      // 50 * 3.0 = 150
      expect(result.interval).toBe(150)
      expect(result.consecutiveCorrect).toBe(6)
      expect(result.easeFactor).toBe(3.1) // 3.0 + 0.1
      expect(result.incorrectCount).toBe(2) // Should not change
    })

    it("should use current date by default", () => {
      const progress: CardProgress = {
        ...INITIAL_PROGRESS,
      }

      const before = new Date()
      const result = calculateCorrectAnswer(progress)
      const after = new Date()

      // Next review should be approximately 1 day from now
      const expectedMin = new Date(before)
      expectedMin.setDate(expectedMin.getDate() + 1)
      const expectedMax = new Date(after)
      expectedMax.setDate(expectedMax.getDate() + 1)

      expect(result.nextReviewDate.getTime()).toBeGreaterThanOrEqual(
        expectedMin.getTime()
      )
      expect(result.nextReviewDate.getTime()).toBeLessThanOrEqual(
        expectedMax.getTime()
      )
    })

    it("should handle large intervals correctly", () => {
      const progress: CardProgress = {
        easeFactor: 2.5,
        interval: 365,
        consecutiveCorrect: 10,
        incorrectCount: 0,
        nextReviewDate: new Date("2026-01-01"),
      }

      const result = calculateCorrectAnswer(progress, new Date("2026-01-01"))

      // 365 * 2.5 = 912.5, rounded = 913
      expect(result.interval).toBe(913)
      expect(result.consecutiveCorrect).toBe(11)
    })
  })

  describe("calculateIncorrectAnswer", () => {
    it("should reset interval to 1", () => {
      const progress: CardProgress = {
        easeFactor: 2.7,
        interval: 16,
        consecutiveCorrect: 3,
        incorrectCount: 0,
        nextReviewDate: new Date("2025-01-17"),
      }

      const result = calculateIncorrectAnswer(progress, new Date("2025-01-17"))

      expect(result.interval).toBe(1)
      expect(result.nextReviewDate).toEqual(new Date("2025-01-18"))
    })

    it("should reset consecutiveCorrect to 0", () => {
      const progress: CardProgress = {
        easeFactor: 2.7,
        interval: 16,
        consecutiveCorrect: 5,
        incorrectCount: 1,
        nextReviewDate: new Date("2025-01-17"),
      }

      const result = calculateIncorrectAnswer(progress, new Date("2025-01-17"))

      expect(result.consecutiveCorrect).toBe(0)
    })

    it("should decrease easeFactor by 0.2", () => {
      const progress: CardProgress = {
        easeFactor: 2.5,
        interval: 6,
        consecutiveCorrect: 2,
        incorrectCount: 0,
        nextReviewDate: new Date("2025-01-07"),
      }

      const result = calculateIncorrectAnswer(progress, new Date("2025-01-07"))

      expect(result.easeFactor).toBe(2.3) // 2.5 - 0.2
    })

    it("should not decrease easeFactor below 1.3", () => {
      const progress: CardProgress = {
        easeFactor: 1.4,
        interval: 1,
        consecutiveCorrect: 0,
        incorrectCount: 5,
        nextReviewDate: new Date("2025-01-02"),
      }

      const result = calculateIncorrectAnswer(progress, new Date("2025-01-02"))

      // 1.4 - 0.2 = 1.2, but minimum is 1.3
      expect(result.easeFactor).toBe(1.3)
    })

    it("should increment incorrectCount", () => {
      const progress: CardProgress = {
        easeFactor: 2.5,
        interval: 6,
        consecutiveCorrect: 2,
        incorrectCount: 0,
        nextReviewDate: new Date("2025-01-07"),
      }

      const result = calculateIncorrectAnswer(progress, new Date("2025-01-07"))

      expect(result.incorrectCount).toBe(1)
    })

    it("should use current date by default", () => {
      const progress: CardProgress = {
        easeFactor: 2.5,
        interval: 6,
        consecutiveCorrect: 2,
        incorrectCount: 0,
        nextReviewDate: new Date("2025-01-07"),
      }

      const before = new Date()
      const result = calculateIncorrectAnswer(progress)
      const after = new Date()

      // Next review should be approximately 1 day from now
      const expectedMin = new Date(before)
      expectedMin.setDate(expectedMin.getDate() + 1)
      const expectedMax = new Date(after)
      expectedMax.setDate(expectedMax.getDate() + 1)

      expect(result.nextReviewDate.getTime()).toBeGreaterThanOrEqual(
        expectedMin.getTime()
      )
      expect(result.nextReviewDate.getTime()).toBeLessThanOrEqual(
        expectedMax.getTime()
      )
    })

    it("should handle multiple consecutive incorrect answers", () => {
      let progress: CardProgress = {
        easeFactor: 2.5,
        interval: 16,
        consecutiveCorrect: 3,
        incorrectCount: 0,
        nextReviewDate: new Date("2025-01-17"),
      }

      // First incorrect
      let result = calculateIncorrectAnswer(progress, new Date("2025-01-17"))
      expect(result.easeFactor).toBe(2.3)
      expect(result.incorrectCount).toBe(1)

      // Second incorrect
      progress = {
        easeFactor: result.easeFactor,
        interval: result.interval,
        consecutiveCorrect: result.consecutiveCorrect,
        incorrectCount: result.incorrectCount,
        nextReviewDate: result.nextReviewDate,
      }
      result = calculateIncorrectAnswer(progress, new Date("2025-01-18"))
      expect(result.easeFactor).toBeCloseTo(2.1) // 2.3 - 0.2
      expect(result.incorrectCount).toBe(2)

      // Third incorrect
      progress = {
        easeFactor: result.easeFactor,
        interval: result.interval,
        consecutiveCorrect: result.consecutiveCorrect,
        incorrectCount: result.incorrectCount,
        nextReviewDate: result.nextReviewDate,
      }
      result = calculateIncorrectAnswer(progress, new Date("2025-01-19"))
      expect(result.easeFactor).toBeCloseTo(1.9) // 2.1 - 0.2
      expect(result.incorrectCount).toBe(3)
    })
  })

  describe("selectCardsForSession", () => {
    const now = new Date("2025-01-15T10:00:00Z")

    it("should select due cards only", () => {
      const cards: SelectableCard[] = [
        {
          id: "1",
          nextReviewDate: new Date("2025-01-14T10:00:00Z"), // Due
          incorrectCount: 0,
          consecutiveCorrect: 1,
          manualDifficulty: Difficulty.MEDIUM,
        },
        {
          id: "2",
          nextReviewDate: new Date("2025-01-16T10:00:00Z"), // Not due
          incorrectCount: 0,
          consecutiveCorrect: 1,
          manualDifficulty: Difficulty.MEDIUM,
        },
        {
          id: "3",
          nextReviewDate: new Date("2025-01-13T10:00:00Z"), // Due
          incorrectCount: 0,
          consecutiveCorrect: 1,
          manualDifficulty: Difficulty.MEDIUM,
        },
      ]

      const selected = selectCardsForSession(cards, 10, now, false)

      expect(selected.length).toBe(2)
      expect(selected.map((c) => c.id)).toContain("1")
      expect(selected.map((c) => c.id)).toContain("3")
      expect(selected.map((c) => c.id)).not.toContain("2")
    })

    it("should exclude suspended cards", () => {
      const cards: SelectableCard[] = [
        {
          id: "1",
          nextReviewDate: new Date("2025-01-14T10:00:00Z"),
          incorrectCount: 0,
          consecutiveCorrect: 1,
          manualDifficulty: Difficulty.MEDIUM,
        },
        {
          id: "2",
          nextReviewDate: new Date("2025-01-14T10:00:00Z"),
          incorrectCount: 0,
          consecutiveCorrect: 1,
          manualDifficulty: Difficulty.SUSPENDED,
        },
      ]

      const selected = selectCardsForSession(cards, 10, now, false)

      expect(selected.length).toBe(1)
      expect(selected[0].id).toBe("1")
    })

    it("should prioritize HARD over NORMAL over EASY", () => {
      const cards: SelectableCard[] = [
        {
          id: "easy",
          nextReviewDate: new Date("2025-01-14T10:00:00Z"),
          incorrectCount: 0,
          consecutiveCorrect: 1,
          manualDifficulty: Difficulty.EASY,
        },
        {
          id: "hard",
          nextReviewDate: new Date("2025-01-14T10:00:00Z"),
          incorrectCount: 0,
          consecutiveCorrect: 1,
          manualDifficulty: Difficulty.HARD,
        },
        {
          id: "normal",
          nextReviewDate: new Date("2025-01-14T10:00:00Z"),
          incorrectCount: 0,
          consecutiveCorrect: 1,
          manualDifficulty: Difficulty.MEDIUM,
        },
      ]

      const selected = selectCardsForSession(cards, 10, now, false)

      expect(selected[0].id).toBe("hard")
      expect(selected[1].id).toBe("normal")
      expect(selected[2].id).toBe("easy")
    })

    it("should sort by nextReviewDate ascending", () => {
      const cards: SelectableCard[] = [
        {
          id: "1",
          nextReviewDate: new Date("2025-01-14T10:00:00Z"),
          incorrectCount: 0,
          consecutiveCorrect: 1,
          manualDifficulty: Difficulty.MEDIUM,
        },
        {
          id: "2",
          nextReviewDate: new Date("2025-01-12T10:00:00Z"),
          incorrectCount: 0,
          consecutiveCorrect: 1,
          manualDifficulty: Difficulty.MEDIUM,
        },
        {
          id: "3",
          nextReviewDate: new Date("2025-01-13T10:00:00Z"),
          incorrectCount: 0,
          consecutiveCorrect: 1,
          manualDifficulty: Difficulty.MEDIUM,
        },
      ]

      const selected = selectCardsForSession(cards, 10, now, false)

      expect(selected[0].id).toBe("2") // Oldest
      expect(selected[1].id).toBe("3")
      expect(selected[2].id).toBe("1") // Newest
    })

    it("should prioritize higher incorrectCount", () => {
      const cards: SelectableCard[] = [
        {
          id: "1",
          nextReviewDate: new Date("2025-01-14T10:00:00Z"),
          incorrectCount: 1,
          consecutiveCorrect: 1,
          manualDifficulty: Difficulty.MEDIUM,
        },
        {
          id: "2",
          nextReviewDate: new Date("2025-01-14T10:00:00Z"),
          incorrectCount: 3,
          consecutiveCorrect: 1,
          manualDifficulty: Difficulty.MEDIUM,
        },
        {
          id: "3",
          nextReviewDate: new Date("2025-01-14T10:00:00Z"),
          incorrectCount: 2,
          consecutiveCorrect: 1,
          manualDifficulty: Difficulty.MEDIUM,
        },
      ]

      const selected = selectCardsForSession(cards, 10, now, false)

      expect(selected[0].id).toBe("2") // incorrectCount: 3
      expect(selected[1].id).toBe("3") // incorrectCount: 2
      expect(selected[2].id).toBe("1") // incorrectCount: 1
    })

    it("should prioritize lower consecutiveCorrect", () => {
      const cards: SelectableCard[] = [
        {
          id: "1",
          nextReviewDate: new Date("2025-01-14T10:00:00Z"),
          incorrectCount: 0,
          consecutiveCorrect: 3,
          manualDifficulty: Difficulty.MEDIUM,
        },
        {
          id: "2",
          nextReviewDate: new Date("2025-01-14T10:00:00Z"),
          incorrectCount: 0,
          consecutiveCorrect: 1,
          manualDifficulty: Difficulty.MEDIUM,
        },
        {
          id: "3",
          nextReviewDate: new Date("2025-01-14T10:00:00Z"),
          incorrectCount: 0,
          consecutiveCorrect: 2,
          manualDifficulty: Difficulty.MEDIUM,
        },
      ]

      const selected = selectCardsForSession(cards, 10, now, false)

      expect(selected[0].id).toBe("2") // consecutiveCorrect: 1
      expect(selected[1].id).toBe("3") // consecutiveCorrect: 2
      expect(selected[2].id).toBe("1") // consecutiveCorrect: 3
    })

    it("should include new cards (null nextReviewDate)", () => {
      const cards: SelectableCard[] = [
        {
          id: "1",
          nextReviewDate: null, // New card
          incorrectCount: 0,
          consecutiveCorrect: 0,
          manualDifficulty: Difficulty.MEDIUM,
        },
        {
          id: "2",
          nextReviewDate: new Date("2025-01-14T10:00:00Z"),
          incorrectCount: 0,
          consecutiveCorrect: 1,
          manualDifficulty: Difficulty.MEDIUM,
        },
      ]

      const selected = selectCardsForSession(cards, 10, now, false)

      expect(selected.length).toBe(2)
      expect(selected[0].id).toBe("1") // New cards first
      expect(selected[1].id).toBe("2")
    })

    it("should limit to cardsPerSession", () => {
      const cards: SelectableCard[] = Array.from({ length: 20 }, (_, i) => ({
        id: `${i}`,
        nextReviewDate: new Date("2025-01-14T10:00:00Z"),
        incorrectCount: 0,
        consecutiveCorrect: 1,
        manualDifficulty: Difficulty.MEDIUM,
      }))

      const selected = selectCardsForSession(cards, 5, now, false)

      expect(selected.length).toBe(5)
    })

    it("should apply all sorting criteria in correct order", () => {
      const cards: SelectableCard[] = [
        {
          id: "easy-old-high-low",
          nextReviewDate: new Date("2025-01-12T10:00:00Z"),
          incorrectCount: 5,
          consecutiveCorrect: 1,
          manualDifficulty: Difficulty.EASY,
        },
        {
          id: "hard-new-low-high",
          nextReviewDate: new Date("2025-01-14T10:00:00Z"),
          incorrectCount: 1,
          consecutiveCorrect: 5,
          manualDifficulty: Difficulty.HARD,
        },
        {
          id: "hard-old-low-low",
          nextReviewDate: new Date("2025-01-12T10:00:00Z"),
          incorrectCount: 1,
          consecutiveCorrect: 1,
          manualDifficulty: Difficulty.HARD,
        },
        {
          id: "normal-old-high-low",
          nextReviewDate: new Date("2025-01-12T10:00:00Z"),
          incorrectCount: 5,
          consecutiveCorrect: 1,
          manualDifficulty: Difficulty.MEDIUM,
        },
      ]

      const selected = selectCardsForSession(cards, 10, now, false)

      // Expected order:
      // 1. HARD difficulty has priority
      // 2. Among HARD: older date (2025-01-12) before newer (2025-01-14)
      // 3. Then NORMAL difficulty
      // 4. Then EASY difficulty
      expect(selected[0].id).toBe("hard-old-low-low")
      expect(selected[1].id).toBe("hard-new-low-high")
      expect(selected[2].id).toBe("normal-old-high-low")
      expect(selected[3].id).toBe("easy-old-high-low")
    })

    it("should handle empty card list", () => {
      const selected = selectCardsForSession([], 10, now, false)
      expect(selected.length).toBe(0)
    })

    it("should handle all cards being suspended", () => {
      const cards: SelectableCard[] = [
        {
          id: "1",
          nextReviewDate: new Date("2025-01-14T10:00:00Z"),
          incorrectCount: 0,
          consecutiveCorrect: 1,
          manualDifficulty: Difficulty.SUSPENDED,
        },
        {
          id: "2",
          nextReviewDate: new Date("2025-01-14T10:00:00Z"),
          incorrectCount: 0,
          consecutiveCorrect: 1,
          manualDifficulty: Difficulty.SUSPENDED,
        },
      ]

      const selected = selectCardsForSession(cards, 10, now, false)
      expect(selected.length).toBe(0)
    })

    it("should handle all cards not being due", () => {
      const cards: SelectableCard[] = [
        {
          id: "1",
          nextReviewDate: new Date("2025-01-16T10:00:00Z"),
          incorrectCount: 0,
          consecutiveCorrect: 1,
          manualDifficulty: Difficulty.MEDIUM,
        },
        {
          id: "2",
          nextReviewDate: new Date("2025-01-17T10:00:00Z"),
          incorrectCount: 0,
          consecutiveCorrect: 1,
          manualDifficulty: Difficulty.MEDIUM,
        },
      ]

      const selected = selectCardsForSession(cards, 10, now, false)
      expect(selected.length).toBe(0)
    })
  })

  describe("generateWrongAnswers", () => {
    const correctAnswer: HanziOption = {
      id: "1",
      simplified: "好",
      pinyin: "hǎo",
      hskLevel: "new-1",
    }

    it("should generate 3 wrong answers", () => {
      const sameHskOptions: HanziOption[] = [
        correctAnswer,
        { id: "2", simplified: "你", pinyin: "nǐ", hskLevel: "new-1" },
        { id: "3", simplified: "我", pinyin: "wǒ", hskLevel: "new-1" },
        { id: "4", simplified: "他", pinyin: "tā", hskLevel: "new-1" },
        { id: "5", simplified: "的", pinyin: "de", hskLevel: "new-1" },
      ]

      const wrongAnswers = generateWrongAnswers(correctAnswer, sameHskOptions)

      expect(wrongAnswers.length).toBe(3)
      expect(wrongAnswers).not.toContain("hǎo") // Should not include correct
    })

    it("should not include correct answer", () => {
      const sameHskOptions: HanziOption[] = [
        correctAnswer,
        { id: "2", simplified: "你", pinyin: "nǐ", hskLevel: "new-1" },
        { id: "3", simplified: "我", pinyin: "wǒ", hskLevel: "new-1" },
        { id: "4", simplified: "他", pinyin: "tā", hskLevel: "new-1" },
      ]

      const wrongAnswers = generateWrongAnswers(correctAnswer, sameHskOptions)

      expect(wrongAnswers).not.toContain("hǎo")
    })

    it("should not include duplicate pinyin", () => {
      const sameHskOptions: HanziOption[] = [
        correctAnswer,
        { id: "2", simplified: "好", pinyin: "hǎo", hskLevel: "new-1" }, // Duplicate pinyin
        { id: "3", simplified: "你", pinyin: "nǐ", hskLevel: "new-1" },
        { id: "4", simplified: "我", pinyin: "wǒ", hskLevel: "new-1" },
        { id: "5", simplified: "他", pinyin: "tā", hskLevel: "new-1" },
        { id: "6", simplified: "的", pinyin: "de", hskLevel: "new-1" },
      ]

      const wrongAnswers = generateWrongAnswers(correctAnswer, sameHskOptions)

      expect(wrongAnswers.length).toBe(3)
      // Should only have 1 instance of each pinyin
      const uniquePinyin = new Set(wrongAnswers)
      expect(uniquePinyin.size).toBe(3)
    })

    it("should throw error if not enough options", () => {
      const sameHskOptions: HanziOption[] = [
        correctAnswer,
        { id: "2", simplified: "你", pinyin: "nǐ", hskLevel: "new-1" },
        { id: "3", simplified: "我", pinyin: "wǒ", hskLevel: "new-1" },
        // Only 2 other options, need 3
      ]

      expect(() =>
        generateWrongAnswers(correctAnswer, sameHskOptions)
      ).toThrow("Not enough wrong answers available")
    })

    it("should randomize the selection", () => {
      const sameHskOptions: HanziOption[] = [
        correctAnswer,
        { id: "2", simplified: "你", pinyin: "nǐ", hskLevel: "new-1" },
        { id: "3", simplified: "我", pinyin: "wǒ", hskLevel: "new-1" },
        { id: "4", simplified: "他", pinyin: "tā", hskLevel: "new-1" },
        { id: "5", simplified: "的", pinyin: "de", hskLevel: "new-1" },
        { id: "6", simplified: "是", pinyin: "shì", hskLevel: "new-1" },
        { id: "7", simplified: "在", pinyin: "zài", hskLevel: "new-1" },
        { id: "8", simplified: "有", pinyin: "yǒu", hskLevel: "new-1" },
      ]

      // Run multiple times and check that we get different results
      const results = new Set<string>()
      for (let i = 0; i < 10; i++) {
        const wrongAnswers = generateWrongAnswers(correctAnswer, sameHskOptions)
        results.add(wrongAnswers.sort().join(","))
      }

      // Should have at least 2 different combinations (very likely with 7 options)
      expect(results.size).toBeGreaterThan(1)
    })
  })

  describe("shuffleOptions", () => {
    it("should return array of same length", () => {
      const options = ["a", "b", "c", "d"]
      const shuffled = shuffleOptions(options)

      expect(shuffled.length).toBe(4)
    })

    it("should contain all original elements", () => {
      const options = ["a", "b", "c", "d"]
      const shuffled = shuffleOptions(options)

      expect(shuffled).toContain("a")
      expect(shuffled).toContain("b")
      expect(shuffled).toContain("c")
      expect(shuffled).toContain("d")
    })

    it("should not mutate original array", () => {
      const options = ["a", "b", "c", "d"]
      const original = [...options]
      shuffleOptions(options)

      expect(options).toEqual(original)
    })

    it("should produce different orders", () => {
      const options = ["a", "b", "c", "d", "e", "f"]

      // Run multiple times and check that we get different results
      const results = new Set<string>()
      for (let i = 0; i < 20; i++) {
        const shuffled = shuffleOptions(options)
        results.add(shuffled.join(","))
      }

      // Should have at least 2 different orderings (very likely with 6 elements)
      expect(results.size).toBeGreaterThan(1)
    })

    it("should handle single element array", () => {
      const options = ["a"]
      const shuffled = shuffleOptions(options)

      expect(shuffled).toEqual(["a"])
    })

    it("should handle empty array", () => {
      const options: string[] = []
      const shuffled = shuffleOptions(options)

      expect(shuffled).toEqual([])
    })

    it("should work with different types", () => {
      const options = [1, 2, 3, 4, 5]
      const shuffled = shuffleOptions(options)

      expect(shuffled.length).toBe(5)
      expect(shuffled).toContain(1)
      expect(shuffled).toContain(2)
      expect(shuffled).toContain(3)
      expect(shuffled).toContain(4)
      expect(shuffled).toContain(5)
    })
  })
})
