<script setup>
import { computed, toValue } from 'vue'
import { Line } from 'vue-chartjs'
import { Chart, registerables } from 'chart.js'
import {
  filterMedicationsForWindow,
  formatMedicationTooltip,
  getMedicationsNearTimestamp,
} from '@/composables/chartMedications'
import { useChartTheme } from '@/composables/useChartTheme'
import { medicationMarkerPlugin } from '@/plugins/medicationMarkerPlugin'

Chart.register(...registerables, medicationMarkerPlugin)

const props = defineProps({
  chartData: { type: Object, required: true },
  title: { type: String, required: true },
  yMin: { type: Number, default: undefined },
  yMax: { type: Number, default: undefined },
  observations: { type: Array, default: () => [] },
  observationCode: { type: String, default: '' },
  medications: { type: Array, default: () => [] },
})

const { buildOptions, darkMode } = useChartTheme()

const lineData = computed(() => {
  const data = toValue(props.chartData)
  return data?.datasets ? data : { labels: [], timestamps: [], datasets: [] }
})

const chartMedications = computed(() =>
  filterMedicationsForWindow(props.observations, props.observationCode, props.medications),
)

const chartOptions = computed(() => {
  darkMode.value
  const options = buildOptions({
    scales: {
      y: { min: props.yMin, max: props.yMax },
      x: { ticks: { maxTicksAuto: true, maxRotation: 45 } },
    },
    plugins: {
      medicationMarkers: {
        medications: chartMedications.value,
        timestamps: lineData.value.timestamps ?? [],
      },
      tooltip: {
        callbacks: {
          afterBody(items) {
            if (!items.length) return []
            const timestamps = lineData.value.timestamps ?? []
            const idx = items[0].dataIndex
            const targetMs = timestamps[idx] ? new Date(timestamps[idx]).getTime() : null
            if (targetMs == null) return []
            return getMedicationsNearTimestamp(chartMedications.value, targetMs)
              .map(formatMedicationTooltip)
          },
        },
      },
    },
  }).value

  return options
})
</script>

<template>
  <div class="w-full min-w-0 rounded-lg border border-gray-200 bg-white p-4 dark:border-gray-700 dark:bg-gray-900">
    <h3 class="mb-4 text-sm font-medium text-gray-700 dark:text-gray-300">{{ title }}</h3>
    <div
      class="aspect-video w-full min-h-[220px] min-w-0 overflow-hidden sm:min-h-0"
      role="img"
      :aria-label="`${title} trend chart`"
    >
      <Line :data="lineData" :options="chartOptions" />
    </div>
  </div>
</template>
