<script setup>
import { computed, shallowRef, markRaw } from 'vue'
import { Chart } from 'vue-chartjs'
import { Chart as ChartJS, registerables } from 'chart.js'
import { formatTime } from '@/composables/chartFormat'

ChartJS.register(...registerables)

const props = defineProps({ history: { type: Array, required: true } })

const ORGAN_DATASETS = [
  { label: 'Respiratory', key: 'respiratoryScore', color: '#3b82f6' },
  { label: 'Coagulation', key: 'coagulationScore', color: '#8b5cf6' },
  { label: 'Liver', key: 'liverScore', color: '#f59e0b' },
  { label: 'Cardiovascular', key: 'cardiovascularScore', color: '#ef4444' },
  { label: 'CNS', key: 'cnsScore', color: '#ec4899' },
  { label: 'Renal', key: 'renalScore', color: '#06b6d4' },
]

function sofaRiskBorder(score) {
  if (score >= 10) return '#dc2626'
  if (score >= 6) return '#f59e0b'
  return '#22c55e'
}

const sortedHistory = computed(() =>
  [...props.history].sort((a, b) => new Date(a.calculatedAt) - new Date(b.calculatedAt)),
)

const chartData = computed(() => {
  const sorted = sortedHistory.value
  const labels = sorted.map(h => formatTime(h.calculatedAt))

  const organDatasets = ORGAN_DATASETS.map(({ label, key, color }) => ({
    type: 'line',
    label,
    data: sorted.map(h => h[key] ?? 0),
    backgroundColor: `${color}66`,
    borderColor: color,
    borderWidth: 1,
    fill: true,
    stack: 'organs',
    pointRadius: 0,
    tension: 0.2,
    order: 2,
  }))

  return {
    labels,
    datasets: [
      ...organDatasets,
      {
        type: 'line',
        label: 'SOFA Total',
        data: sorted.map(h => h.totalScore),
        borderColor: '#111827',
        backgroundColor: 'transparent',
        pointBackgroundColor: sorted.map(h => sofaRiskBorder(h.totalScore)),
        pointBorderColor: sorted.map(h => sofaRiskBorder(h.totalScore)),
        pointRadius: 4,
        borderWidth: 2,
        fill: false,
        tension: 0.3,
        order: 1,
      },
    ],
  }
})

const chartOptions = shallowRef(markRaw({
  responsive: true,
  maintainAspectRatio: true,
  animation: {
    duration: window.matchMedia('(prefers-reduced-motion: reduce)').matches ? 0 : 400,
  },
  interaction: { mode: 'index', intersect: false },
  scales: {
    x: { stacked: true },
    y: {
      stacked: true,
      min: 0,
      max: 24,
      title: { display: true, text: 'SOFA Score' },
    },
  },
  plugins: {
    legend: {
      display: true,
      position: 'bottom',
      labels: { boxWidth: 12, font: { size: 11 } },
    },
    tooltip: {
      callbacks: {
        footer(items) {
          const total = items.find(i => i.dataset.label === 'SOFA Total')
          if (!total) return ''
          const score = total.parsed.y
          if (score >= 10) return 'Risk: High (≥10)'
          if (score >= 6) return 'Risk: Moderate (6–9)'
          return 'Risk: Low (0–5)'
        },
      },
    },
  },
}))
</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-1 text-sm font-medium text-gray-700 dark:text-gray-300">SOFA Score Over Time</h3>
    <p class="mb-4 text-xs text-gray-500 dark:text-gray-400">
      Stacked areas show per-organ contributions; line shows total score.
      <span class="text-green-600 dark:text-green-400">0–5</span>,
      <span class="text-amber-600 dark:text-amber-400">6–9</span>,
      <span class="text-red-600 dark:text-red-400">10+</span>.
    </p>
    <div class="aspect-video w-full min-h-0 overflow-hidden">
      <Chart type="line" :data="chartData" :options="chartOptions" />
    </div>
  </div>
</template>
