import onFind from './dom/onFind'
import create from './dom/create'
import storage from './util/storage'

interface PanelData {
  typeId: string
  panelId?: string
  width?: string
}

let panelData: PanelData | null

let pointerIsDown = false
let pdOriginX = 0 // Pointer down origin x position
let gtcOrigin: number[] = [] // Origin Grid Template Columns in pixels
let ogTransProp: undefined | string
let isRTL = false // Whether the container has RTL direction
let container: HTMLElement | null // The target Page
let panel: HTMLElement | null // The target Panel

const updateWidth = (length: string) => {
  if (!container) {
    container = document.querySelector<HTMLElement>('.Page-content, .Popup')
  }
  document.documentElement.style.setProperty('--contentForm-resized-w', length)
  setTimeout(() => window.dispatchEvent(new Event('resize')), 100)
}

const getPreferredWidth = (data: PanelData) => {
  return storage.get(`BSP.ContentEdit.form/${data.typeId}/width`)
}

const savePreferredWidth = (data: PanelData) => {
  if (!data || !data.width) return
  storage.set(`BSP.ContentEdit.form/${data.typeId}/width`, data.width)
}

/* Add behavior for Preview "show/hide actions" toggle */
onFind('.PreviewFrame-moreActions', (moreActions: HTMLButtonElement) => {
  moreActions.addEventListener('click', () => {
    moreActions.toggleAttribute('aria-expanded')
  })
})

const onPointerDown = (e: PointerEvent) => {
  if (e.target instanceof HTMLElement) {
    if (e.target.classList.contains('ContentEdit-resizeWrapper')) {
      container = e.target.closest<HTMLElement>('.Page-content, .Popup')
      if (!container) return
      pointerIsDown = true
      const isPopup = container.classList.contains('Popup')
      if (isPopup) {
        container.style.cursor = 'col-resize'
        container.style.userSelect = 'none'
      } else {
        document.body.style.cursor = 'col-resize'
        document.body.style.userSelect = 'none'
      }
      pdOriginX = e.screenX
      const computedStyle = getComputedStyle(container)
      ogTransProp = computedStyle.transitionProperty
      isRTL = computedStyle.direction === 'rtl'
      container.style.transitionProperty = 'none'
      const grid = isPopup
        ? container.querySelector<HTMLElement>('.Popup-content')
        : container
      if (!grid) return

      gtcOrigin = window
        .getComputedStyle(grid)
        .gridTemplateColumns.split(' ')
        .map((a: string) => +a.slice(0, -2))

      const isPreviewing = container.closest<HTMLElement>(
        '.Page-content.is-previewing, .Popup.is-previewing',
      )
      const preview = container.querySelector<HTMLElement>(
        '.PreviewFrame-typeDisplay',
      )
      if (isPreviewing && preview) {
        preview.style.filter = 'grayscale(100%) blur(1px)'
        preview.inert = true
        panel = preview
        panelData = {
          typeId:
            container.querySelector<HTMLElement>('.ContentEdit')?.dataset
              .typeId || '',
          panelId: 'preview',
        }
      } else {
        panel = container.querySelector<HTMLElement>(
          '.ContentEdit-right.is-visible',
        )
        panelData = {
          typeId:
            panel?.closest<HTMLElement>('.ContentEdit')?.dataset.typeId || '',
          panelId: panel?.dataset.rightTab || '',
        }
      }
    }
  }
}

const onPointerUp = (e: PointerEvent) => {
  panel = null
  pointerIsDown = false
  if (e.target instanceof HTMLElement) {
    container = e.target.closest<HTMLElement>('.Page-content, .Popup')
  }
  if (container && ogTransProp) {
    container.style.transitionProperty = ogTransProp
  }
  if (container?.classList.contains('Popup')) {
    container.style.cursor = 'initial'
    container.style.userSelect = 'unset'
  } else {
    document.body.style.cursor = 'initial'
    document.body.style.userSelect = 'unset'
  }

  const preview = container?.querySelector<HTMLElement>(
    '.PreviewFrame-typeDisplay',
  )
  if (preview) {
    preview.style.filter = 'unset'
    preview.inert = false
    setTimeout(() => window.dispatchEvent(new Event('resize')), 200)
  }

  if (panelData && panelData.width) {
    savePreferredWidth(panelData)
    panelData = null
  }
}

const onPointerMove = (e: PointerEvent) => {
  if (pointerIsDown && panelData) {
    if (!container) return
    let changeX = e.screenX - pdOriginX

    // In RTL layouts, invert the mouse movement direction
    if (isRTL) {
      changeX = -changeX
    }

    let origin = gtcOrigin[0] // Default to the first column
    if (container.querySelector('.LiveBlogPostList')) {
      origin = gtcOrigin[3]
    }

    const w = Math.round(origin + changeX) + 'px'
    document.documentElement.style.setProperty('--contentForm-resized-w', w)
    panelData.width = w
  }
}

const initResizablePanel = () => {
  onFind('.ContentEdit-main', (cl) => {
    cl.append(
      create(
        'div',
        { className: 'ContentEdit-resizeWrapper' },
        create('div', { className: 'ContentEdit-resizeHandle' }),
      ),
    )
  })

  document.body.addEventListener('pointerdown', onPointerDown, false)
  document.body.addEventListener('pointerup', onPointerUp, false)
  document.body.addEventListener('pointermove', onPointerMove, false)

  // Check if there's a preferred width for the content form
  const contentEdit = document.querySelector<HTMLElement>('.ContentEdit')
  if (contentEdit) {
    const w = getPreferredWidth({
      typeId: contentEdit.dataset.typeId || '',
    })
    if (w) {
      updateWidth(w)
    }
  }
}

if (document.readyState === 'loading') {
  window.addEventListener('DOMContentLoaded', initResizablePanel)
} else {
  initResizablePanel()
}
