import { describe, it, expect, vi } from 'vitest'
import { render, screen } from '@testing-library/react'
import { LassoToolsProvider, useLassoToolsState } from './provider'
import { createLassoToolsStore } from './store'

describe('LassoToolsProvider', () => {
  it('should provide lasso tools context to children', () => {
    const TestComponent = () => {
      const enabled = useLassoToolsState(
        (state) => state.data['test-map']?.enabled,
      )
      return <div data-testid='enabled'>{String(enabled)}</div>
    }

    render(
      <LassoToolsProvider values={[{ mapId: 'test-map', enabled: true }]}>
        <TestComponent />
      </LassoToolsProvider>,
    )

    expect(screen.getByTestId('enabled').textContent).toBe('true')
  })

  it('should throw error when useLassoToolsState is used outside provider', () => {
    const TestComponent = () => {
      useLassoToolsState((state) => state.data)
      return <div>Test</div>
    }

    // Suppress console.error for this test
    const consoleSpy = vi.spyOn(console, 'error').mockImplementation(() => {
      /* empty */
    })

    expect(() => render(<TestComponent />)).toThrow(
      'Missing LassoToolsProvider in the tree',
    )

    consoleSpy.mockRestore()
  })

  it('should allow multiple map instances', () => {
    const TestComponent = () => {
      const map1Enabled = useLassoToolsState(
        (state) => state.data['map-1']?.enabled,
      )
      const map2Enabled = useLassoToolsState(
        (state) => state.data['map-2']?.enabled,
      )
      return (
        <div>
          <div data-testid='map1'>{String(map1Enabled)}</div>
          <div data-testid='map2'>{String(map2Enabled)}</div>
        </div>
      )
    }

    render(
      <LassoToolsProvider
        values={[
          { mapId: 'map-1', enabled: true },
          { mapId: 'map-2', enabled: false },
        ]}
      >
        <TestComponent />
      </LassoToolsProvider>,
    )

    expect(screen.getByTestId('map1').textContent).toBe('true')
    expect(screen.getByTestId('map2').textContent).toBe('false')
  })
})

describe('lasso tools store messages', () => {
  it('addMessage dedups by id (at most one message per entity) and removeMessage clears it', () => {
    const store = createLassoToolsStore([{ mapId: 'test-map' }])
    const { addMessage, removeMessage } = store.getState()

    addMessage('test-map', { id: 'geom-1', title: 'first', severity: 'info' })
    addMessage('test-map', {
      id: 'geom-1',
      title: 'replaced',
      severity: 'warning',
    })

    expect(store.getState().data['test-map']?.messages).toEqual([
      { id: 'geom-1', title: 'replaced', severity: 'warning' },
    ])

    removeMessage('test-map', 'geom-1')

    expect(store.getState().data['test-map']?.messages).toEqual([])
  })
})
