import { useContext, act } from 'react'
import { describe, it, expect, beforeEach, vi } from 'vitest'
import { createRoot } from 'react-dom/client'

describe('ConnectionProvider singleton behavior', () => {
  beforeEach(async () => {
    vi.resetModules()
  })

  it('creates only one UniversalWalletConnector across multiple providers', async () => {
    vi.doMock('@meshconnect/uwc-core', () => {
      class UniversalWalletConnector {
        static calls = 0

        constructor() {
          UniversalWalletConnector.calls++
        }

        // Minimal API used by the provider
        getSession() {
          return {
            isConnected: false,
            walletId: undefined,
            networkId: undefined
          }
        }

        isReady() {
          return true
        }

        subscribe() {
          return () => {}
        }

        getWallets() {
          return []
        }

        getNetworks() {
          return []
        }
      }

      return { UniversalWalletConnector }
    })

    const { ConnectionProvider, ConnectionContext } =
      await import('./ConnectionProvider')
    const { UniversalWalletConnector } = await import('@meshconnect/uwc-core')
    const connectors: unknown[] = []

    function Capture() {
      const ctx = useContext(ConnectionContext)
      if (ctx) {
        connectors.push(ctx.connector)
      }
      return null
    }

    const container = document.createElement('div')
    document.body.appendChild(container)
    const root = createRoot(container)

    await act(async () => {
      root.render(
        <>
          <ConnectionProvider
            networks={[]}
            wallets={[]}
            usingIntegratedBrowser={false}
          >
            <Capture />
          </ConnectionProvider>
          <ConnectionProvider
            networks={[]}
            wallets={[]}
            usingIntegratedBrowser={false}
          >
            <Capture />
          </ConnectionProvider>
        </>
      )
    })

    // Only one constructor call expected due to singleton guard
    // @ts-expect-error test-only property
    expect(UniversalWalletConnector.calls).toBe(1)

    // Both providers should expose the same connector instance
    expect(connectors.length).toBe(2)
    expect(connectors[0]).toBe(connectors[1])

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