import { fixture, assert, html, oneEvent, nextFrame, aTimeout } from '@open-wc/testing'
import sinon from 'sinon'
import PrismHighlight from '../../../src/elements/highlight/PrismHighlight.js'
import '../../../src/elements/highlight/prism-highlight.js'

describe('PrismHighlightElement', () => {
  async function markdownFixture(): Promise<PrismHighlight> {
    return fixture(html`<prism-highlight lang="markdown"></prism-highlight>`)
  }

  async function rawFixture(): Promise<PrismHighlight> {
    return fixture(html`<prism-highlight raw lang="json" code='{"test": true}'></prism-highlight>`)
  }

  describe('anchors handling', () => {
    let element: PrismHighlight
    let code = '# Test highlight\nHello world!\n'
    code += '[link](https://domain.com/)'

    beforeEach(async () => {
      element = await markdownFixture()
      element.code = code
      // one for the setter
      await nextFrame()
      // and one for the highlight debouncer (do we still need it?)
      await aTimeout(0)
      await nextFrame()
    })

    // Not sure why but when executing this file only this works, but in the test run it cannot find the "a" element.
    it.skip('dispatches the link event', async () => {
      const anchor = element.outputElement!.querySelector('a')!
      setTimeout(() => {
        anchor.click()
      })
      const e = await oneEvent(element, 'link')
      assert.equal(e.detail.url, 'https://domain.com/', 'has the URL value')
      assert.equal(e.detail.asNew, false, 'has the asNew property')
    })

    // auto liner is disabled due to some error with dart syntax language.
    it.skip('dispatches the event when ctrl is set', async () => {
      const spy = sinon.spy()
      element.addEventListener('link', spy)
      const anchor = element.outputElement!.querySelector('a')!
      anchor.dispatchEvent(
        new PointerEvent('click', {
          bubbles: true,
          cancelable: true,
          composed: true,
          ctrlKey: true,
        })
      )
      assert.isTrue(spy.calledOnce)
      const event = spy.args[0][0] as CustomEvent
      assert.equal(event.detail.url, 'https://domain.com/', 'has the URL value')
      assert.equal(event.detail.asNew, true, 'has the asNew property')
    })
  })

  describe('#raw', () => {
    let element: PrismHighlight
    beforeEach(async () => {
      element = await rawFixture()
    })

    it('renders the code without highlighting', () => {
      const pre = element.shadowRoot!.querySelector('.raw-content')!
      assert.ok(pre)
    })

    it('renders back the highlighted document', async () => {
      element.raw = false
      await nextFrame()
      const pre = element.shadowRoot!.querySelector('.parsed-content')
      assert.ok(pre)
    })
  })
})
