// @vitest-environment jsdom
import React, { act } from 'react'
import { createRoot } from 'react-dom/client'
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
import InstantLoadHarness from '../src/islands/InstantLoadHarness'

const vitalsSpies = vi.hoisted(() => ({
  onCLS: vi.fn((reporter) => reporter({ name: 'CLS', value: 0 })),
  onFCP: vi.fn(),
  onINP: vi.fn(),
  onLCP: vi.fn(),
  onTTFB: vi.fn(),
}))

vi.mock('web-vitals', () => vitalsSpies)

describe('instant-load consumer smoke', () => {
  let host: HTMLDivElement

  beforeEach(() => {
    globalThis.IS_REACT_ACT_ENVIRONMENT = true
    vi.useFakeTimers()
    window.localStorage.clear()
    window.sessionStorage.clear()
    host = document.createElement('div')
    document.body.appendChild(host)
  })

  afterEach(() => {
    vi.useRealTimers()
    vi.clearAllMocks()
    host.remove()
  })

  it('proves cold, cached, refresh, and cls-oracle flows', async () => {
    const first = createRoot(host)
    await act(async () => {
      first.render(React.createElement(InstantLoadHarness))
    })

    await act(async () => {
      await vi.runAllTimersAsync()
    })

    expect(host.querySelector('[data-testid="boot-mode"]')?.textContent).toBe('cold')
    expect(host.querySelector('[data-testid="query-result"]')?.textContent).toContain('Version 1')

    await act(async () => {
      first.unmount()
    })

    const second = createRoot(host)
    await act(async () => {
      second.render(React.createElement(InstantLoadHarness))
    })

    await act(async () => {
      await vi.runAllTimersAsync()
    })

    expect(host.querySelector('[data-testid="boot-mode"]')?.textContent).toBe('cached')
    expect(host.querySelector('[data-testid="query-result"]')?.textContent).toContain('Version 1')

    await act(async () => {
      ;(host.querySelector('[data-testid="source-bump"]') as HTMLButtonElement).click()
      ;(host.querySelector('[data-testid="query-refresh"]') as HTMLButtonElement).click()
    })

    expect(host.querySelector('[data-testid="query-result"]')?.textContent).toContain('Version 1')

    await act(async () => {
      await vi.runAllTimersAsync()
    })

    expect(host.querySelector('[data-testid="query-result"]')?.textContent).toContain('Version 2')
    expect(host.querySelector('[data-testid="cls-oracle"]')?.getAttribute('data-cls')).toBe('0.0000')

    await act(async () => {
      second.unmount()
    })
  })
})
