import router from '@/router'
import store from '@/store'

let iframe = null

// === Section related actions ===
export const addSection = (content, section, insertAt) => {
  postMessage('section:add', { content, section, insertAt })
}

export const moveSection = (content, sectionId, targetSectionId, direction) => {
  postMessage('section:move', {
    content,
    sectionId,
    targetSectionId,
    direction,
  })
}

// the editor modifies the content of a section setting
export const updateSection = (content, section, change) => {
  postMessage('section:update', { content, section, change })
}

export const removeSection = (sectionId) => {
  postMessage('section:remove', { sectionId })
}

// === Block related actions ===
export const addBlock = (content, section, sectionBlock) => {
  postMessage('block:add', { content, section, sectionBlock })
}

export const moveBlock = (content, section) => {
  postMessage('block:move', { content, section })
}

export const updateBlock = (content, section, sectionBlock, change) => {
  postMessage('block:update', { content, section, sectionBlock, change })
}

export const removeBlock = (content, section, sectionBlockId) => {
  postMessage('block:remove', { content, section, sectionBlockId })
}

// === Other actions ===

export const updateStyle = (content, style) => {
  postMessage('style:update', { content, style })
}

// Start everything
export const start = (newIframe) => {
  // keep a reference to the current iframe
  iframe = newIframe

  // say hi to the iFrame by giving it the configuration
  postMessage('config', {
    primaryColor: store.state.editorSettings.primaryColor,
    stickySectionIds: store.getters.stickySectionList.map(
      (section) => section.id,
    ),
  })

  // treat all the message coming from the iFrame
  listenMessages()
}

const listenMessages = () => {
  window.addEventListener('message', ({ data: { type, ...data } }) => {
    // a message MUST have a type
    if (!type) return

    switch (type) {
      case 'ready':
        store.dispatch('markPreviewAsReady')
        break
      case 'scroll':
        notifyScrolling(data.boundingRect)
        break
      case 'section:hover': {
        store.dispatch('hoverSection', {
          sectionId: data.sectionId,
          sectionRect: data.sectionRect,
          sectionOffsetTop: data.sectionOffsetTop, //sectionOffsetHeight,
        })
        break
      }
      case 'section:leave':
        store.dispatch('leaveSection')
        break
      case 'section:setting:clicked':
        openSettingPane('editSectionSetting', data)
        break
      case 'sectionBlock:setting:clicked':
        openSettingPane('editSectionBlockSetting', data)
        break
      default:
        break
    }
  })
}

const postMessage = (type, data) => {
  if (!iframe) return null
  iframe.contentWindow.postMessage({ type, ...(data || {}) }, '*')
}

const openSettingPane = (name, params) => {
  let route = { name, params, hash: '#content' }
  router.push(route).catch((err) => {
    if (err.name !== 'NavigationDuplicated') throw err
  })
}

const notifyScrolling = (boundingRect) => {
  const event = new CustomEvent('maglev:preview:scroll', {
    detail: { boundingRect },
  })
  window.dispatchEvent(event)
}