import { readFileSync } from 'node:fs'
import { resolve } from 'node:path'
import { describe, it, expect, vi } from 'vitest'
import { mountSuspended } from '@nuxt/test-utils/runtime'
import KestrelMap from '../../app/components/KestrelMap.vue'

vi.mock('leaflet', () => ({ default: {} }))
vi.mock('leaflet.offline', () => ({ tileLayerOffline: null, savetiles: null }))

describe('KestrelMap', () => {
  it('renders map container', async () => {
    const wrapper = await mountSuspended(KestrelMap, {
      props: { devices: [] },
    })
    expect(wrapper.find('[data-testid="kestrel-map"]').exists()).toBe(true)
  })

  it('accepts devices prop', async () => {
    const devices = [
      { id: '1', name: 'A', lat: 37.7, lng: -122.4, streamUrl: '', sourceType: 'mjpeg' },
    ]
    const wrapper = await mountSuspended(KestrelMap, {
      props: { devices },
    })
    expect(wrapper.props('devices')).toEqual(devices)
  })

  it('has select emit', async () => {
    const wrapper = await mountSuspended(KestrelMap, {
      props: { devices: [] },
    })
    wrapper.vm.$emit('select', { id: 'x', name: 'X', lat: 0, lng: 0 })
    expect(wrapper.emitted('select')).toHaveLength(1)
  })

  it('uses dark Carto tile URL with subdomains', async () => {
    const componentPath = resolve(__dirname, '../../app/components/KestrelMap.vue')
    const source = readFileSync(componentPath, 'utf-8')
    expect(source).toContain('basemaps.cartocdn.com/dark_all')
    expect(source).toContain('{s}.basemaps.cartocdn.com')
  })

  it('requests client location first with maximumAge 0 so browser prompts', async () => {
    const componentPath = resolve(__dirname, '../../app/components/KestrelMap.vue')
    const source = readFileSync(componentPath, 'utf-8')
    expect(source).toContain('getCurrentPosition')
    expect(source).toContain('enableHighAccuracy: true')
    expect(source).toContain('maximumAge: 0')
    expect(source).toContain('createMap([latitude, longitude])')
  })

  it('uses L.tileLayer for base display so tiles load from OSM', async () => {
    const componentPath = resolve(__dirname, '../../app/components/KestrelMap.vue')
    const source = readFileSync(componentPath, 'utf-8')
    expect(source).toContain('L.tileLayer(TILE_URL')
    expect(source).toContain('baseLayer.addTo(map)')
  })

  it('sets Leaflet default marker icon path to avoid Vue Router intercept', async () => {
    const componentPath = resolve(__dirname, '../../app/components/KestrelMap.vue')
    const source = readFileSync(componentPath, 'utf-8')
    expect(source).toContain('Icon.Default.mergeOptions')
    expect(source).toContain('marker-icon.png')
    expect(source).toContain('marker-shadow.png')
  })

  it('accepts pois and canEditPois props', async () => {
    const wrapper = await mountSuspended(KestrelMap, {
      props: {
        devices: [],
        pois: [{ id: 'p1', lat: 37.7, lng: -122.4, label: 'P', icon_type: 'pin' }],
        canEditPois: false,
      },
    })
    expect(wrapper.props('pois')).toHaveLength(1)
    expect(wrapper.props('canEditPois')).toBe(false)
  })

  it('includes CoT layer toggles and supercluster layer', async () => {
    const componentPath = resolve(__dirname, '../../app/components/KestrelMap.vue')
    const source = readFileSync(componentPath, 'utf-8')
    expect(source).toContain('cot-layer-toggles')
    expect(source).toContain('cotMapLayer')
    expect(source).toContain('syncCotLayer')
  })
})
