<script setup lang="ts">
import { ref, onMounted, onBeforeUnmount, watch, nextTick, defineExpose } from 'vue'
import { echarts } from '@/lib/echarts'

const props = defineProps<{ option: any }>()

const root = ref<HTMLDivElement | null>(null)
let chart: echarts.ECharts | null = null
let ro: ResizeObserver | null = null

function init() {
  if (!root.value || chart) return
  chart = echarts.init(root.value)
  if ('ResizeObserver' in window) {
    ro = new ResizeObserver(() => {
      chart && chart.resize()
    })
    ro.observe(root.value)
  }
  window.addEventListener('resize', handleResize, { passive: true })
}
function handleResize() {
  chart && chart.resize()
}
function dispose() {
  if (ro && root.value) ro.unobserve(root.value)
  ro = null
  window.removeEventListener('resize', handleResize)
  if (chart) {
    chart.dispose()
    chart = null
  }
}

function getOptionToApply(): any {
  const o: any = props.option
  if (!o) return null
  if (o.toolbox) {
    const tb = { ...(o.toolbox || {}), show: false }
    return { ...o, toolbox: tb }
  }
  return o
}
function applyOption() {
  if (!chart || !props.option) return
  const opt = getOptionToApply()
  if (!opt) return
  chart.setOption(opt, {
    notMerge: true,
    replaceMerge: ['toolbox', 'legend', 'grid', 'xAxis', 'yAxis', 'dataZoom', 'series', 'dataset'],
    lazyUpdate: false,
    silent: true,
  })
}

function onRestore() {
  applyOption()
}
function onSaveImage() {
  if (!chart) return
  const url = chart.getDataURL({ type: 'png', pixelRatio: 2, backgroundColor: '#ffffff' })
  const a = document.createElement('a')
  a.href = url
  a.download = 'chart.png'
  a.click()
}

onMounted(async () => {
  init()
  await nextTick()
  applyOption()
})
onBeforeUnmount(() => {
  dispose()
})
watch(
  () => props.option,
  async () => {
    await nextTick()
    if (!chart) init()
    applyOption()
  },
  { deep: true }
)

defineExpose({
  saveImage: onSaveImage,
  restore: onRestore,
  resize: handleResize,
})
</script>

<template>
  <div class="relative w-full">
    <div ref="root" class="w-full h-full min-h-[260px]" />
  </div>
</template>
