import Cookies from 'js-cookie'
import create from './dom/create'
import onFind from './dom/onFind'
import Preview from './main/webapp/v4/ViewPreview'

onFind('.ContentSummary-info', (info: HTMLElement) => {
  contentSummaryEvent(info)
})

onFind('input[data-summary-url]', (element: HTMLElement) => {
  const updateButton = () => {
    const containerElement = element.parentElement
    if (containerElement) {
      let contentSummaryButton: HTMLButtonElement | null
      if (
        containerElement.tagName.includes('-') &&
        containerElement.parentElement
      ) {
        contentSummaryButton =
          containerElement.parentElement.querySelector<HTMLButtonElement>(
            '.ContentSummary-info',
          )
      } else {
        contentSummaryButton =
          containerElement.querySelector<HTMLButtonElement>(
            '.ContentSummary-info',
          )
      }
      const summaryUrl = element.dataset.summaryUrl
      if (summaryUrl) {
        if (contentSummaryButton) {
          contentSummaryButton.setAttribute('data-summary-url', summaryUrl)
        } else {
          contentSummaryButton = create('button', {
            class: 'ContentSummary-info',
            'aria-haspopup': true,
            'data-summary-url': summaryUrl,
          })

          const objectIdEdit =
            containerElement.querySelector<HTMLElement>('.objectId-edit')
          if (objectIdEdit) {
            objectIdEdit.insertAdjacentElement('afterend', contentSummaryButton)
          }
        }
      }
      if (contentSummaryButton) {
        updateDataSummaryUrl(element, contentSummaryButton)
      }
    }
  }
  updateButton()
  const observer = new MutationObserver(updateButton)

  observer.observe(element, {
    attributes: true,
    attributeFilter: ['data-summary-url'],
  })
})

function updateDataSummaryUrl(
  element: HTMLElement,
  contentSummaryButton: HTMLButtonElement,
) {
  const dataSummaryUrl = element.dataset.summaryUrl
  if (dataSummaryUrl) {
    contentSummaryButton.setAttribute('data-summary-url', dataSummaryUrl)
  } else {
    if (contentSummaryButton) {
      contentSummaryButton.remove()
    }
  }
}

export const contentSummaryEvent = (info: HTMLElement) => {
  let summary: HTMLElement | null = null

  info.addEventListener('click', handler)
  info.addEventListener('keydown', (event) => {
    if (
      event.key === 'Tab' &&
      summary &&
      summary.classList.contains('is-open')
    ) {
      handler(event)
    }
  })

  async function handler(event: Event) {
    event.preventDefault()
    event.stopImmediatePropagation()
    event.stopPropagation()

    document
      .querySelectorAll('.ContentSummary-popup')
      .forEach((popup: Element) => {
        $(popup).popup('close')
      })

    const target = event.target

    if (!(target instanceof HTMLElement)) {
      return
    }

    const url = target.getAttribute('data-summary-url')
    const error = target.querySelector('.error-message')

    if (info.hasAttribute('aria-expanded')) {
      info.removeAttribute('aria-expanded')
    } else {
      info.setAttribute('aria-expanded', 'true')

      // Trigger live region if already displayed prior.
      if (summary) {
        const content = summary.innerHTML
        summary.innerHTML = ''
        summary.innerHTML = content
      }
    }

    if (!url && !error) {
      return
    }

    if (!summary) {
      if (error) {
        summary = create('div', {
          className: 'ContentSummary error-summary',
          innerHTML: error.innerHTML,
        })
      } else if (url) {
        const csrf = Cookies.get('bsp.csrf')

        if (csrf) {
          const response = await fetch(url, {
            headers: {
              'Brightspot-CSRF': csrf,
            },
          })

          summary = create('div', {
            className: 'ContentSummary',
            innerHTML: await response.text(),
          })

          summary.focus()
        }
      }

      if (summary) {
        document.body.appendChild(summary)
      }
    }

    info.classList.toggle('is-active')
    target.previousElementSibling?.classList.toggle('is-active')

    if (summary) {
      summary.classList.toggle('is-open')

      const $popup = $(summary).popup()
      $popup
        .popup('container')
        .addClass('ContentSummary-popup')
        .toggleClass(
          'is-preview',
          summary?.querySelector('.Widget-title.is-preview') !== null,
        )
      $popup.popup('source', $(info))
      $popup.popup('open')

      $popup.closest('.Popup').on('close.popup', () => {
        info.classList.toggle('is-active')
        target.previousElementSibling?.classList.toggle('is-active')
        summary = null
      })

      const previewFrame = summary.querySelector('.PreviewFrame')
      if (previewFrame) {
        const preview = new Preview(previewFrame)
        preview.isVisible = true
        preview.reloadPreview()

        // When iframe has loaded post message to disable pointer events so contents
        // can not be clicked.
        const observer = new MutationObserver((mutationList) => {
          mutationList.forEach((mutation) => {
            mutation.addedNodes.forEach((node) => {
              if (node instanceof HTMLIFrameElement) {
                iframePostMessage(node)
              }
            })
            if (
              mutation.previousSibling &&
              mutation.previousSibling instanceof HTMLIFrameElement
            ) {
              iframePostMessage(mutation.previousSibling)
            }
          })
        })

        observer.observe(previewFrame, {
          attributes: false,
          childList: true,
          subtree: true,
        })
      }
    }
  }
}

function iframePostMessage(node: HTMLIFrameElement) {
  if (node.contentWindow) {
    node.contentWindow.postMessage(
      {
        type: 'BSP.Preview.PointerEvents',
        value: 'none',
      },
      '*',
    )
  }
}
