/**
 * ECharts integration for FixIt shortcode blocks.
 *
 * Responsibilities:
 * - Initialize ECharts instances with light/dark theme support.
 * - Re-render all charts on theme switch.
 * - Resize charts on window resize events.
 * - Re-run initialization when `fixit:content-decrypted` is emitted.
 */
import { eventBus } from '../core/event-bus'
import { getStagingDOM, isDarkMode, isObjectLiteral } from '../utils'

let echartsArr: any[] = []

function initEchartsInTarget(target: Element | Document = document) {
  const echarts = window.echarts
  const config = window.config.echarts
  if (!echarts || !config)
    return
  const isDark = isDarkMode()
  const stagingDOM = getStagingDOM()
  target.querySelectorAll('.echarts').forEach(($echarts: Element) => {
    const $dataEl = $echarts.nextElementSibling as HTMLElement
    if ($dataEl.tagName !== 'TEMPLATE')
      return
    const chart = echarts.init($echarts as HTMLElement, isDark ? 'dark' : 'light', { renderer: 'svg' })
    chart.showLoading()
    stagingDOM.stage(($dataEl as HTMLTemplateElement).content.cloneNode(true))
    const _setOption = (option: any) => {
      if (!option) {
        chart.hideLoading()
        console.warn('ECharts option is missing or invalid. Chart disposed.', {
          element: $echarts,
          option: $dataEl,
        })
        chart.dispose()
        ;($echarts as HTMLElement).removeAttribute('style')
        return
      }
      chart.hideLoading()
      chart.setOption(option)
      echartsArr.push(chart)
    }
    if ($dataEl.dataset.fmt === 'js') {
      try {
        const jsCodes = stagingDOM.contentAsText()
        // eslint-disable-next-line no-new-func
        const _getOption = new Function('fixit', 'chart', isObjectLiteral(jsCodes) ? `return ${jsCodes}` : jsCodes)
        if ($dataEl.dataset.async === 'true') {
          return Promise.resolve(_getOption(window.fixit, chart)).then((option: any) => {
            _setOption(option)
          })
        }
        return _setOption(_getOption(window.fixit, chart))
      }
      catch (err) {
        return console.error(err)
      }
    }
    _setOption(stagingDOM.contentAsJson())
  })
  stagingDOM.destroy()
}

function applyEchartsTheme() {
  const echarts = window.echarts
  const config = window.config.echarts
  if (!echarts || !config)
    return
  echarts.registerTheme('light', config.lightTheme!)
  echarts.registerTheme('dark', config.darkTheme!)
  echartsArr.forEach(chart => chart.dispose())
  echartsArr = []
  initEchartsInTarget()
}

document.addEventListener('DOMContentLoaded', () => {
  applyEchartsTheme()
  eventBus.on('fixit:switch-theme', ({ detail }) => {
    if (!detail.isChanged)
      return
    applyEchartsTheme()
  })
  eventBus.on('fixit:resize', () => {
    echartsArr.forEach(chart => chart.resize())
  })
  eventBus.on('fixit:content-decrypted', ({ detail }) => {
    if (detail.isPage) {
      applyEchartsTheme()
      return
    }
    initEchartsInTarget(detail.target)
  })
}, false)
