import { assert, fixture, html, nextFrame } from '@open-wc/testing'
import '../../../src/elements/mention-textarea/ui-mention-textarea.js'

type MentionTextAreaElement =
  import('../../../src/elements/mention-textarea/ui-mention-textarea.js').MentionTextAreaElement

describe('MentionTextArea - Basic Tests', () => {
  async function basicFixture(): Promise<MentionTextAreaElement> {
    return fixture(html`<mention-textarea></mention-textarea>`)
  }

  function getEditor(element: MentionTextAreaElement): HTMLElement {
    return element.shadowRoot!.querySelector('.editor')!
  }

  describe('basic functionality', () => {
    it('should render with default properties', async () => {
      const element = await basicFixture()

      assert.isNotNull(element)
      assert.equal(element.label, '')
      assert.equal(element.value, '')
      assert.equal(element.mentionTrigger, '@')
      assert.equal(element.minQueryLength, 0)
      assert.isFalse(element.disabled)
      assert.isFalse(element.required)
    })

    it('should have proper shadow DOM structure', async () => {
      const element = await basicFixture()

      const container = element.shadowRoot!.querySelector('.container')
      const editor = getEditor(element)

      assert.isNotNull(container)
      assert.isNotNull(editor)
      assert.equal(editor.getAttribute('contenteditable'), 'true')
      assert.equal(editor.getAttribute('role'), 'textbox')
    })

    it('should update value when set programmatically', async () => {
      const element = await basicFixture()

      element.value = 'Test value'
      await nextFrame()

      assert.equal(element.value, 'Test value')

      const editor = getEditor(element)
      assert.equal(editor.textContent, 'Test value')
    })

    it('should handle disabled state', async () => {
      const element = await basicFixture()
      element.disabled = true
      await nextFrame()

      const editor = getEditor(element)
      assert.equal(editor.getAttribute('contenteditable'), 'false')
      assert.equal(editor.getAttribute('tabindex'), '-1')
    })
  })

  describe('mentions getter - basic tests', () => {
    it('should return empty array for empty value', async () => {
      const element = await basicFixture()

      assert.deepEqual(element.mentions, [])
    })

    it('should return empty array for text without mentions', async () => {
      const element = await basicFixture()
      element.value = 'Hello world'
      await nextFrame()

      assert.deepEqual(element.mentions, [])
    })

    it('should extract mention IDs from value', async () => {
      const element = await basicFixture()
      element.value = 'Hello @{user1} and @{user2}'
      await nextFrame()

      const mentions = element.mentions.sort()
      assert.deepEqual(mentions, ['user1', 'user2'])
    })
  })

  describe('getPlainText method - basic tests', () => {
    it('should return same text when no mentions', async () => {
      const element = await basicFixture()
      element.value = 'Hello world'
      await nextFrame()

      assert.equal(element.getPlainText(), 'Hello world')
    })

    it('should replace mentions with IDs when no suggestions', async () => {
      const element = await basicFixture()
      element.value = 'Hello @{user1} world'
      await nextFrame()

      assert.equal(element.getPlainText(), 'Hello user1 world')
    })

    it('should handle empty value', async () => {
      const element = await basicFixture()
      element.value = ''
      await nextFrame()

      assert.equal(element.getPlainText(), '')
    })
  })
})
