/* eslint-disable @typescript-eslint/ban-ts-comment */
import { assert, fixture, html } from '@open-wc/testing'
import sinon from 'sinon'
import { AmfEvents, AmfEventTypes } from '../../../src/index.js'

describe('Events', () => {
  async function etFixture(): Promise<HTMLDivElement> {
    return fixture(html`<div></div>`)
  }

  describe('Events.Endpoint', () => {
    describe('get()', () => {
      const id = 'amf://id'

      it('dispatches the event', async () => {
        const et = await etFixture()
        const spy = sinon.spy()
        et.addEventListener(AmfEventTypes.Endpoint.get, spy)
        AmfEvents.Endpoint.get(et, id)
        assert.isTrue(spy.calledOnce)
      })

      it('the event has the "id" property', async () => {
        const et = await etFixture()
        const spy = sinon.spy()
        et.addEventListener(AmfEventTypes.Endpoint.get, spy)
        AmfEvents.Endpoint.get(et, id)
        assert.deepEqual(spy.args[0][0].detail.id, id)
      })

      it('waits until resolved', async () => {
        const et = await etFixture()
        const data = { test: true }
        et.addEventListener(AmfEventTypes.Endpoint.get, (e) => {
          ;(e as CustomEvent).detail.result = Promise.resolve(data)
        })
        const result = await AmfEvents.Endpoint.get(et, id)
        // @ts-ignore
        assert.deepEqual(result, data)
      })
    })

    describe('byPath()', () => {
      const path = 'amf://id'

      it('dispatches the event', async () => {
        const et = await etFixture()
        const spy = sinon.spy()
        et.addEventListener(AmfEventTypes.Endpoint.byPath, spy)
        AmfEvents.Endpoint.byPath(et, path)
        assert.isTrue(spy.calledOnce)
      })

      it('the event has the "id" property', async () => {
        const et = await etFixture()
        const spy = sinon.spy()
        et.addEventListener(AmfEventTypes.Endpoint.byPath, spy)
        AmfEvents.Endpoint.byPath(et, path)
        assert.deepEqual(spy.args[0][0].detail.id, path)
      })

      it('waits until resolved', async () => {
        const et = await etFixture()
        const data = /** @type any */ { test: true }
        et.addEventListener(AmfEventTypes.Endpoint.byPath, (e) => {
          // @ts-ignore
          e.detail.result = Promise.resolve(data)
        })
        const result = await AmfEvents.Endpoint.byPath(et, path)
        // @ts-ignore
        assert.deepEqual(result, data)
      })
    })

    describe('list()', () => {
      it('dispatches the event', async () => {
        const et = await etFixture()
        const spy = sinon.spy()
        et.addEventListener(AmfEventTypes.Endpoint.list, spy)
        AmfEvents.Endpoint.list(et)
        assert.isTrue(spy.calledOnce)
      })

      it('waits until resolved', async () => {
        const et = await etFixture()
        et.addEventListener(AmfEventTypes.Endpoint.list, (e) => {
          // @ts-ignore
          e.detail.result = Promise.resolve()
        })
        await AmfEvents.Endpoint.list(et)
      })
    })
  })
})
