<script setup lang="ts">
import { ref, onMounted, onUnmounted, watch, nextTick } from 'vue'
import uPlot from 'uplot'
import 'uplot/dist/uPlot.min.css'

export interface TimeSeriesSeries {
  label: string
  color: string
}

const props = withDefaults(defineProps<{
  /** Array of series configs (label + color) */
  series: TimeSeriesSeries[]
  /** Data: [timestamps[], series1[], series2[], ...] */
  data: uPlot.AlignedData
  /** Chart title (optional) */
  title?: string
  /** Stacked area mode */
  stacked?: boolean
}>(), {
  stacked: false,
})

const container = ref<HTMLElement | null>(null)
let chart: uPlot | null = null

function buildOpts(): uPlot.Options {
  const seriesOpts: uPlot.Series[] = [
    { label: 'Time' },
    ...props.series.map((s) => ({
      label: s.label,
      stroke: s.color,
      fill: props.stacked ? s.color + '40' : undefined,
      width: 2,
    })),
  ]

  return {
    width: container.value?.clientWidth ?? 400,
    height: container.value?.clientHeight ?? 200,
    series: seriesOpts,
    axes: [
      { stroke: '#555568', grid: { stroke: '#2e2e3822' } },
      { stroke: '#555568', grid: { stroke: '#2e2e3822' } },
    ],
    cursor: { show: true },
    legend: { show: true },
  }
}

function createChart() {
  if (!container.value) return
  if (chart) chart.destroy()
  chart = new uPlot(buildOpts(), props.data, container.value)
}

function resize() {
  if (!chart || !container.value) return
  chart.setSize({
    width: container.value.clientWidth,
    height: container.value.clientHeight,
  })
}

watch(() => props.data, (newData) => {
  if (chart) {
    chart.setData(newData)
  } else {
    nextTick(createChart)
  }
}, { deep: true })

onMounted(() => {
  nextTick(createChart)
  const observer = new ResizeObserver(resize)
  if (container.value) observer.observe(container.value)
  onUnmounted(() => {
    observer.disconnect()
    chart?.destroy()
    chart = null
  })
})
</script>

<template>
  <div ref="container" class="timeseries-renderer" />
</template>

<style scoped>
.timeseries-renderer {
  width: 100%;
  height: 100%;
  min-height: 150px;
}

.timeseries-renderer :deep(.u-legend) {
  font-family: var(--font-mono);
  font-size: var(--font-size-sm);
  color: var(--text-secondary);
}
</style>
