import { describe, expect, test, beforeEach } from 'vitest'
import { useLayers } from './use-layers'
import { useLayerStore } from './providers/layers/store'
import { useMapStore } from './providers/map/provider'
import { render } from '../tests/providers'
import { MAP_ID } from '../tests/config'

describe('useLayers', () => {
  beforeEach(() => {
    // Reset stores before each test
    useLayerStore.setState({ layers: {} })
  })

  test('returns empty array when no layers exist', () => {
    const TestComponent = () => {
      const layers = useLayers({ mapId: MAP_ID })
      return <div data-testid='count'>{layers.length}</div>
    }

    const { container } = render(<TestComponent />)
    const countDiv = container.querySelector('[data-testid="count"]')
    expect(countDiv?.textContent).toBe('0')
  })

  test('returns layers associated with the map', () => {
    const TestComponent = () => {
      // Setup: Add a layer to the store and map
      const setLayer = useLayerStore((state) => state.setLayer)
      const addLayers = useMapStore((state) => state.addLayers)

      // Add layer to store
      setLayer('layer-1', {
        type: null,
        props: { id: 'layer-1', visible: true },
      })

      // Add layer to map
      addLayers(MAP_ID, ['layer-1'])

      const layers = useLayers({ mapId: MAP_ID })
      return <div data-testid='count'>{layers.length}</div>
    }

    const { container } = render(<TestComponent />)
    const countDiv = container.querySelector('[data-testid="count"]')
    expect(countDiv?.textContent).toBe('1')
  })

  test('filters out invalid layers', () => {
    const TestComponent = () => {
      const addLayers = useMapStore((state) => state.addLayers)
      const setLayer = useLayerStore((state) => state.setLayer)

      // Add valid layer
      setLayer('layer-1', {
        type: null,
        props: { id: 'layer-1', visible: true },
      })
      addLayers(MAP_ID, ['layer-1'])

      // Add non-existent layer to map (should be filtered out)
      addLayers(MAP_ID, ['non-existent-layer'])

      const layers = useLayers({ mapId: MAP_ID })
      return <div data-testid='count'>{layers.length}</div>
    }

    const { container } = render(<TestComponent />)
    const countDiv = container.querySelector('[data-testid="count"]')
    expect(countDiv?.textContent).toBe('1')
  })

  test('returns multiple layers in correct order', () => {
    const TestComponent = () => {
      const setLayer = useLayerStore((state) => state.setLayer)
      const addLayers = useMapStore((state) => state.addLayers)

      // Add multiple layers
      setLayer('layer-1', {
        type: null,
        props: { id: 'layer-1', visible: true },
      })
      setLayer('layer-2', {
        type: null,
        props: { id: 'layer-2', visible: false },
      })
      setLayer('layer-3', {
        type: null,
        props: { id: 'layer-3', visible: true },
      })

      addLayers(MAP_ID, ['layer-1', 'layer-2', 'layer-3'])

      const layers = useLayers({ mapId: MAP_ID })
      return (
        <div>
          <div data-testid='count'>{layers.length}</div>
          <div data-testid='first-id'>{layers[0]?.props.id}</div>
          <div data-testid='second-id'>{layers[1]?.props.id}</div>
          <div data-testid='third-id'>{layers[2]?.props.id}</div>
        </div>
      )
    }

    const { container } = render(<TestComponent />)
    expect(container.querySelector('[data-testid="count"]')?.textContent).toBe(
      '3',
    )
    expect(
      container.querySelector('[data-testid="first-id"]')?.textContent,
    ).toBe('layer-1')
    expect(
      container.querySelector('[data-testid="second-id"]')?.textContent,
    ).toBe('layer-2')
    expect(
      container.querySelector('[data-testid="third-id"]')?.textContent,
    ).toBe('layer-3')
  })

  test('memoizes computed layers correctly', () => {
    let renderCount = 0

    const TestComponent = () => {
      const setLayer = useLayerStore((state) => state.setLayer)
      const addLayers = useMapStore((state) => state.addLayers)

      // Setup initial layer
      if (renderCount === 0) {
        setLayer('layer-1', {
          type: null,
          props: { id: 'layer-1', visible: true },
        })
        addLayers(MAP_ID, ['layer-1'])
      }

      const layers = useLayers({ mapId: MAP_ID })
      renderCount++

      return <div data-testid='count'>{layers.length}</div>
    }

    const { rerender, container } = render(<TestComponent />)

    const firstCount = container.querySelector(
      '[data-testid="count"]',
    )?.textContent
    const initialRenderCount = renderCount

    // Re-render without changes
    rerender(<TestComponent />)

    const secondCount = container.querySelector(
      '[data-testid="count"]',
    )?.textContent

    expect(firstCount).toBe(secondCount)
    expect(renderCount).toBeGreaterThan(initialRenderCount)
  })
})
