import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'
import { mount } from '@vue/test-utils'
import { nextTick } from 'vue'
import TutorialOverlay from '../TutorialOverlay.vue'
import * as controller from '../controller'
import { stepRegistry, type StepDef } from '../steps'

const baseStep: StepDef = stepRegistry['setup-parent-pin']!

describe('TutorialOverlay', () => {
  beforeEach(() => {
    controller.activeStep.value = null
    controller.sessionSkipped.value = false
    global.fetch = vi.fn().mockResolvedValue({ ok: true })
  })

  afterEach(() => {
    controller.activeStep.value = null
    document.body.innerHTML = ''
  })

  function mountOverlay() {
    return mount(TutorialOverlay, { attachTo: document.body })
  }

  it('renders "Continue" and "Cancel" labels by default', async () => {
    controller.activeStep.value = {
      def: baseStep,
      anchor: null,
    }
    const wrapper = mountOverlay()
    await nextTick()

    const root = document.body.querySelector('.tutorial-root')
    expect(root).not.toBeNull()
    expect(root!.querySelector('.btn-primary')?.textContent?.trim()).toBe('Continue')
    expect(root!.querySelector('.btn-skip')?.textContent?.trim()).toBe('Cancel')

    wrapper.unmount()
  })

  it('uses a custom CTA label when the step defines one', async () => {
    controller.activeStep.value = {
      def: { ...baseStep, ctaLabel: 'Got it' },
      anchor: null,
    }
    const wrapper = mountOverlay()
    await nextTick()

    const root = document.body.querySelector('.tutorial-root')
    expect(root!.querySelector('.btn-primary')?.textContent?.trim()).toBe('Got it')

    wrapper.unmount()
  })

  it('calls dismissActive(true) when the primary button is clicked', async () => {
    const spy = vi.spyOn(controller, 'dismissActive')
    controller.activeStep.value = {
      def: baseStep,
      anchor: null,
    }
    const wrapper = mountOverlay()
    await nextTick()

    const root = document.body.querySelector('.tutorial-root')
    await root!.querySelector('.btn-primary')!.dispatchEvent(new Event('click'))

    expect(spy).toHaveBeenCalledWith(true)

    spy.mockRestore()
    wrapper.unmount()
  })

  it('calls skipSession when the Cancel button is clicked', async () => {
    const spy = vi.spyOn(controller, 'skipSession')
    controller.activeStep.value = {
      def: baseStep,
      anchor: null,
    }
    const wrapper = mountOverlay()
    await nextTick()

    const root = document.body.querySelector('.tutorial-root')
    await root!.querySelector('.btn-skip')!.dispatchEvent(new Event('click'))

    expect(spy).toHaveBeenCalled()

    spy.mockRestore()
    wrapper.unmount()
  })
})
