// @vitest-environment jsdom
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
import { renderHook } from '@testing-library/react'

import { useProductWorkspaceStore } from '@/stores/product-workspace/store'
import { useWorkspaceResync } from '@/lib/realtime/use-workspace-resync'

let resyncSpy: ReturnType<typeof vi.fn>

beforeEach(() => {
  resyncSpy = vi.fn().mockResolvedValue(undefined)
  useProductWorkspaceStore.setState((s) => {
    s.resyncActiveScopes = resyncSpy as unknown as typeof s.resyncActiveScopes
  })
  // visibilitychange handler leest document.visibilityState — default is 'visible'
  Object.defineProperty(document, 'visibilityState', {
    value: 'visible',
    writable: true,
    configurable: true,
  })
})

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

describe('useWorkspaceResync', () => {
  it('triggert resyncActiveScopes("visible") op visibilitychange hidden→visible', () => {
    renderHook(() => useWorkspaceResync())

    Object.defineProperty(document, 'visibilityState', {
      value: 'visible',
      writable: true,
      configurable: true,
    })
    document.dispatchEvent(new Event('visibilitychange'))

    expect(resyncSpy).toHaveBeenCalledWith('visible')
  })

  it('triggert resyncActiveScopes("reconnect") op online-event', () => {
    renderHook(() => useWorkspaceResync())
    window.dispatchEvent(new Event('online'))
    expect(resyncSpy).toHaveBeenCalledWith('reconnect')
  })

  it('triggert geen resync bij visibilitychange naar hidden', () => {
    renderHook(() => useWorkspaceResync())

    Object.defineProperty(document, 'visibilityState', {
      value: 'hidden',
      writable: true,
      configurable: true,
    })
    document.dispatchEvent(new Event('visibilitychange'))

    expect(resyncSpy).not.toHaveBeenCalled()
  })

  it('cleanup verwijdert listeners bij unmount', () => {
    const { unmount } = renderHook(() => useWorkspaceResync())
    unmount()

    window.dispatchEvent(new Event('online'))
    document.dispatchEvent(new Event('visibilitychange'))

    expect(resyncSpy).not.toHaveBeenCalled()
  })
})
