import React from 'react'
import { renderToStaticMarkup } from 'react-dom/server'
import { describe, expect, it } from 'vitest'
import {
  CaRenderer,
  getCaRendererRuntime,
  listCompatibleCaRendererRuntimes,
  listCaRendererRuntimes,
  registerCaRendererRuntime
} from '../admin/src/CaRenderer.js'

describe('CA renderer runtimes', () => {
  it('registers built-in renderers and resolves aliases', () => {
    expect(listCaRendererRuntimes().map((runtime) => runtime.id)).toEqual(
      expect.arrayContaining(['2d-canvas', 'elementary-1d', 'wildfire-2d', 'voxel-3d'])
    )
    expect(getCaRendererRuntime('three-voxel')?.id).toBe('voxel-3d')
    expect(getCaRendererRuntime('elementary-ca')?.id).toBe('elementary-1d')
    expect(getCaRendererRuntime('forest-fire-2d')?.id).toBe('wildfire-2d')
  })

  it('lets custom renderers register with the shared renderer contract', () => {
    registerCaRendererRuntime({
      id: 'test-renderer',
      label: 'Test renderer',
      supportedClasses: [{ dimensions: 2, states: 3 }],
      Component: function TestRenderer() {
        return React.createElement('div', null)
      }
    })

    expect(getCaRendererRuntime('test-renderer')?.label).toBe('Test renderer')
  })

  it('filters renderers by dimensionality and state space', () => {
    expect(listCompatibleCaRendererRuntimes({ dimensions: 3, states: 2 }).map((runtime) => runtime.id)).toEqual([
      'voxel-3d'
    ])
    expect(listCompatibleCaRendererRuntimes({ dimensions: 1, states: 2 }).map((runtime) => runtime.id)).toEqual([
      'elementary-1d'
    ])
    expect(listCompatibleCaRendererRuntimes({ dimensions: 2, states: 3 }).map((runtime) => runtime.id)).toContain(
      'test-renderer'
    )
  })

  it('refuses to render a runtime for an incompatible CA space', () => {
    const markup = renderToStaticMarkup(
      React.createElement(CaRenderer, {
        caption: '',
        cells: [[false]],
        settings: {
          caClass: { dimensions: 3, states: 2 },
          renderer: { id: '2d-canvas' }
        },
        onCellsChange: () => undefined
      })
    )

    expect(markup).toContain('does not support this CA space')
    expect(markup).not.toContain('Game of Life cell editor')
  })

  it('rejects duplicate renderer ids', () => {
    expect(() =>
      registerCaRendererRuntime({
        id: '2d-canvas',
        label: 'Duplicate canvas',
        supportedClasses: [{ dimensions: 2, states: 2 }],
        Component: function DuplicateRenderer() {
          return React.createElement('div', null)
        }
      })
    ).toThrow('already registered')
  })
})
