import { describe, it, expect } from 'vitest'
import { generateMergeSortSteps, generateQuickSortSteps, generateRandomArray } from '../utils/sortAnimations.js'

describe('generateMergeSortSteps', () => {
  it('should produce steps for a small array', () => {
    const arr = [3, 1, 2]
    const steps = generateMergeSortSteps(arr)
    expect(steps.length).toBeGreaterThan(0)
    // 最后一步应标记全部已排序
    const last = steps[steps.length - 1]
    expect(last.highlights.sorted).toEqual([0, 1, 2])
    expect(last.description).toContain('完成')
  })

  it('should sort the array correctly', () => {
    const arr = [5, 3, 8, 1, 9, 2]
    const steps = generateMergeSortSteps(arr)
    const last = steps[steps.length - 1]
    // 检查最终数组有序
    const sorted = [...last.array].sort((a, b) => a - b)
    expect(last.array).toEqual(sorted)
  })

  it('should handle single element array', () => {
    const steps = generateMergeSortSteps([42])
    expect(steps.length).toBeGreaterThan(0)
    expect(steps[steps.length - 1].highlights.sorted).toEqual([0])
  })

  it('should handle empty array', () => {
    const steps = generateMergeSortSteps([])
    expect(steps.length).toBeGreaterThan(0)
  })

  it('should have description for every step', () => {
    const steps = generateMergeSortSteps([4, 2, 7, 1])
    for (const step of steps) {
      expect(step.description).toBeTruthy()
      expect(typeof step.description).toBe('string')
    }
  })

  it('should record array state at each step', () => {
    const arr = [4, 2, 7, 1]
    const steps = generateMergeSortSteps(arr)
    for (const step of steps) {
      expect(Array.isArray(step.array)).toBe(true)
      expect(step.array.length).toBe(arr.length)
    }
  })
})

describe('generateQuickSortSteps', () => {
  it('should produce steps for a small array', () => {
    const arr = [3, 1, 2]
    const steps = generateQuickSortSteps(arr)
    expect(steps.length).toBeGreaterThan(0)
    const last = steps[steps.length - 1]
    expect(last.highlights.sorted).toEqual([0, 1, 2])
    expect(last.description).toContain('完成')
  })

  it('should sort the array correctly', () => {
    const arr = [5, 3, 8, 1, 9, 2]
    const steps = generateQuickSortSteps(arr)
    const last = steps[steps.length - 1]
    const sorted = [...last.array].sort((a, b) => a - b)
    expect(last.array).toEqual(sorted)
  })

  it('should handle single element array', () => {
    const steps = generateQuickSortSteps([42])
    expect(steps.length).toBeGreaterThan(0)
    expect(steps[steps.length - 1].highlights.sorted).toEqual([0])
  })

  it('should handle already sorted array', () => {
    const arr = [1, 2, 3, 4, 5]
    const steps = generateQuickSortSteps(arr)
    const last = steps[steps.length - 1]
    expect(last.array).toEqual([1, 2, 3, 4, 5])
  })

  it('should handle reverse sorted array', () => {
    const arr = [5, 4, 3, 2, 1]
    const steps = generateQuickSortSteps(arr)
    const last = steps[steps.length - 1]
    expect(last.array).toEqual([1, 2, 3, 4, 5])
  })

  it('should have description for every step', () => {
    const steps = generateQuickSortSteps([4, 2, 7, 1])
    for (const step of steps) {
      expect(step.description).toBeTruthy()
    }
  })
})

describe('generateRandomArray', () => {
  it('should generate array of correct size', () => {
    const arr = generateRandomArray(10)
    expect(arr.length).toBe(10)
  })

  it('should generate positive numbers', () => {
    const arr = generateRandomArray(20)
    for (const v of arr) {
      expect(v).toBeGreaterThanOrEqual(1)
    }
  })

  it('should respect maxValue', () => {
    const arr = generateRandomArray(50, 10)
    for (const v of arr) {
      expect(v).toBeLessThanOrEqual(10)
    }
  })
})
