import { mount } from '@vue/test-utils'
import { nextTick } from 'vue'
import { beforeEach, describe, expect, it, vi } from 'vitest'

import MonitorEcgStrip from './MonitorEcgStrip.vue'

describe('MonitorEcgStrip', () => {
  beforeEach(() => {
    vi.useFakeTimers()
  })

  it('renders an ECG svg shell with a waveform path', () => {
    const wrapper = mount(MonitorEcgStrip, {
      props: {
        mode: 'ready',
      },
    })

    expect(wrapper.get('[data-testid="monitor-ecg-strip"]')).toBeTruthy()
    expect(wrapper.get('[data-testid="monitor-ecg-svg"]')).toBeTruthy()

    const path = wrapper.get('[data-testid="monitor-ecg-line"]')
    expect(path.attributes('d')).toBeTruthy()
    expect(path.attributes('d')?.length).toBeGreaterThan(50)
  })

  it('switches visual mode between ready and processing', async () => {
    const wrapper = mount(MonitorEcgStrip, {
      props: {
        mode: 'ready',
      },
    })

    expect(wrapper.classes()).toContain('mode-ready')
    expect((wrapper.element as HTMLElement).style.getPropertyValue('--monitor-ecg-duration')).toBe('3s')

    await wrapper.setProps({ mode: 'processing' })
    await nextTick()

    expect(wrapper.classes()).toContain('mode-processing')
    expect((wrapper.element as HTMLElement).style.getPropertyValue('--monitor-ecg-duration')).toBe('1.6s')
  })

  it('animates with irregular heartbeat pulses', async () => {
    const wrapper = mount(MonitorEcgStrip, {
      props: {
        mode: 'processing',
        random: () => 0,
        beatRangeMs: { min: 100, max: 100 },
      },
    })

    const track = wrapper.get('.monitor-ecg-track')
    expect(track.attributes('style') || '').toContain('translateY(0px) scaleY(1)')

    vi.advanceTimersByTime(100)
    await nextTick()
    expect(track.attributes('style') || '').toContain('translateY(-1.4px) scaleY(1.12)')

    vi.advanceTimersByTime(120)
    await nextTick()
    expect(track.attributes('style') || '').toContain('translateY(0.6px) scaleY(1.03)')

    vi.advanceTimersByTime(110)
    await nextTick()
    expect(track.attributes('style') || '').toContain('translateY(0px) scaleY(1)')
  })
})
