import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'
import { useAutoRefresh, useNowTimer } from '@/composables/useAutoRefresh'

// Mock Vue's onUnmounted
vi.mock('vue', async () => {
  const actual = await vi.importActual('vue')
  return {
    ...actual,
    onUnmounted: vi.fn(),
  }
})

describe('useAutoRefresh', () => {
  beforeEach(() => {
    vi.useFakeTimers()
  })

  afterEach(() => {
    vi.useRealTimers()
  })

  describe('useAutoRefresh', () => {
    it('should call callback at specified interval', () => {
      const callback = vi.fn()
      const { start } = useAutoRefresh(callback, 1000)

      start()
      expect(callback).not.toHaveBeenCalled()

      vi.advanceTimersByTime(1000)
      expect(callback).toHaveBeenCalledTimes(1)

      vi.advanceTimersByTime(1000)
      expect(callback).toHaveBeenCalledTimes(2)
    })

    it('should stop calling callback after stop()', () => {
      const callback = vi.fn()
      const { start, stop } = useAutoRefresh(callback, 1000)

      start()
      vi.advanceTimersByTime(1000)
      expect(callback).toHaveBeenCalledTimes(1)

      stop()
      vi.advanceTimersByTime(2000)
      expect(callback).toHaveBeenCalledTimes(1) // Still 1
    })

    it('should track running state', () => {
      const callback = vi.fn()
      const { start, stop, isRunning } = useAutoRefresh(callback, 1000)

      expect(isRunning.value).toBe(false)

      start()
      expect(isRunning.value).toBe(true)

      stop()
      expect(isRunning.value).toBe(false)
    })

    it('should restart interval on restart()', () => {
      const callback = vi.fn()
      const { start, restart } = useAutoRefresh(callback, 1000)

      start()
      vi.advanceTimersByTime(500)

      restart()
      vi.advanceTimersByTime(500)
      expect(callback).not.toHaveBeenCalled() // Timer was reset

      vi.advanceTimersByTime(500)
      expect(callback).toHaveBeenCalledTimes(1)
    })
  })

  describe('useNowTimer', () => {
    it('should update now value every second', () => {
      const { now, start } = useNowTimer()
      const initialValue = now.value

      start()

      vi.advanceTimersByTime(1000)
      expect(now.value).toBeGreaterThan(initialValue)

      vi.advanceTimersByTime(1000)
      expect(now.value).toBeGreaterThan(initialValue + 1)
    })

    it('should stop updating after stop()', () => {
      const { now, start, stop } = useNowTimer()

      start()
      vi.advanceTimersByTime(1000)
      const valueAfterStart = now.value

      stop()
      vi.advanceTimersByTime(2000)
      expect(now.value).toBe(valueAfterStart)
    })
  })
})
