<template>
  <section class="chart-card card-glow">
    <div class="card-header">
      <div>
        <h2 class="card-title">Historique systeme</h2>
        <p class="card-copy">CPU, RAM et debit reseau sur les derniers releves</p>
      </div>

      <div class="toggle-group" role="radiogroup" aria-label="Metrique affichee">
        <label
          v-for="option in options"
          :key="option.value"
          class="toggle-pill"
          :class="{ 'toggle-pill-active': selectedMetric === option.value }"
        >
          <input
            v-model="selectedMetric"
            type="radio"
            name="system-metric"
            class="sr-only"
            :value="option.value"
          >
          <span class="toggle-dot" :style="{ backgroundColor: option.color }" />
          <span>{{ option.label }}</span>
        </label>
      </div>
    </div>

    <div class="chart-shell">
      <template v-if="loading && points.length === 0">
        <div class="chart-skeleton animate-shimmer" />
      </template>
      <template v-else>
        <div class="chart-meta">
          <div>
            <span class="meta-label">Actuel</span>
            <strong class="meta-value" :style="{ color: activeOption.color }">{{ formattedCurrentValue }}</strong>
          </div>
          <div>
            <span class="meta-label">Pic</span>
            <strong class="meta-value">{{ formattedPeakValue }}</strong>
          </div>
          <div>
            <span class="meta-label">Echelle</span>
            <strong class="meta-value">{{ scaleLabel }}</strong>
          </div>
        </div>

        <svg
          class="chart-svg"
          viewBox="0 0 960 320"
          preserveAspectRatio="none"
          aria-label="Graphique des ressources"
        >
          <line
            v-for="line in gridLines"
            :key="line"
            x1="0"
            :y1="line"
            x2="960"
            :y2="line"
            class="grid-line"
          />
          <polyline
            :points="polylinePoints"
            class="chart-line"
            :style="{ stroke: activeOption.color }"
          />
        </svg>
      </template>
    </div>
  </section>
</template>

<script setup lang="ts">
import {computed, ref, watch} from "vue"

type MetricKey = "cpu" | "ram" | "incoming" | "outgoing"

type SystemMetrics = {
  cpuPercent: number
  memoryPercent: number
  totalMemory: number
  usedMemory: number
  incomingMbps: number
  outgoingMbps: number
  sampledAt: string
}

type HistoryPoint = {
  sampledAt: string
  cpu: number
  ram: number
  incoming: number
  outgoing: number
}

const props = defineProps<{
  metrics: SystemMetrics | null
  loading: boolean
}>()

const selectedMetric = ref<MetricKey>("ram")
const history = ref<HistoryPoint[]>([])
const maxPoints = 40

const options: Array<{value: MetricKey; label: string; color: string}> = [
  {value: "cpu", label: "CPU", color: "#5aa9ff"},
  {value: "ram", label: "RAM", color: "#31c48d"},
  {value: "incoming", label: "Entrant", color: "#f59e0b"},
  {value: "outgoing", label: "Sortant", color: "#ef4444"}
]

watch(
  () => props.metrics?.sampledAt,
  () => {
    if (!props.metrics) {
      return
    }

    history.value = [
      ...history.value,
      {
        sampledAt: props.metrics.sampledAt,
        cpu: props.metrics.cpuPercent,
        ram: props.metrics.memoryPercent,
        incoming: props.metrics.incomingMbps,
        outgoing: props.metrics.outgoingMbps
      }
    ].slice(-maxPoints)
  },
  {immediate: true}
)

const activeOption = computed(() => {
  return options.find((option) => option.value === selectedMetric.value) || options[0]
})

const points = computed(() => history.value.map((point) => point[selectedMetric.value]))

const peakValue = computed(() => {
  return points.value.reduce((max, value) => Math.max(max, value), 0)
})

const scaleMax = computed(() => {
  if (selectedMetric.value === "cpu" || selectedMetric.value === "ram") {
    return 100
  }

  return Math.max(1, Math.ceil(peakValue.value))
})

const formatValue = (value: number, metric: MetricKey) => {
  if (metric === "cpu" || metric === "ram") {
    return `${Math.round(value)}%`
  }

  return `${value.toFixed(2)} Mbps`
}

const formattedCurrentValue = computed(() => {
  const currentValue = points.value.at(-1) ?? 0
  return formatValue(currentValue, selectedMetric.value)
})

const formattedPeakValue = computed(() => {
  return formatValue(peakValue.value, selectedMetric.value)
})

const scaleLabel = computed(() => {
  return formatValue(scaleMax.value, selectedMetric.value)
})

const gridLines = [40, 120, 200, 280]

const polylinePoints = computed(() => {
  if (points.value.length === 0) {
    return "0,280"
  }

  if (points.value.length === 1) {
    const normalizedValue = points.value[0] / scaleMax.value
    const y = 280 - normalizedValue * 240
    return `0,${y} 960,${y}`
  }

  return points.value
    .map((value, index) => {
      const x = (index / (points.value.length - 1)) * 960
      const normalizedValue = scaleMax.value > 0 ? value / scaleMax.value : 0
      const y = 280 - normalizedValue * 240

      return `${x},${Math.max(24, Math.min(280, y))}`
    })
    .join(" ")
})
</script>

<style scoped>
.chart-card {
  margin-top: 1.5rem;
  background: rgb(var(--m-secondary));
  border-radius: 12px;
  padding: 1.25rem;
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.card-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
}

.card-title {
  font-family: var(--font-display);
  font-size: 1.25rem;
  font-weight: 700;
  color: rgb(var(--m-text));
}

.card-copy {
  margin-top: 0.25rem;
  font-family: var(--font-mono);
  font-size: 0.75rem;
  color: rgb(var(--m-muted));
  text-transform: uppercase;
  letter-spacing: 0.12em;
}

.toggle-group {
  display: flex;
  align-items: center;
  gap: 0.625rem;
  flex-wrap: wrap;
}

.toggle-pill {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  border-radius: 999px;
  border: 1px solid rgb(var(--m-accent) / 0.1);
  background: rgb(var(--m-tertiary));
  padding: 0.55rem 0.8rem;
  font-family: var(--font-mono);
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: rgb(var(--m-muted));
  cursor: pointer;
  transition: border-color 0.2s ease, color 0.2s ease, transform 0.2s ease;
}

.toggle-pill-active {
  border-color: rgb(var(--m-accent) / 0.28);
  color: rgb(var(--m-text));
  transform: translateY(-1px);
}

.toggle-dot {
  width: 10px;
  height: 10px;
  border-radius: 999px;
  flex-shrink: 0;
}

.chart-shell {
  border-radius: 12px;
  padding: 1rem;
  background:
    linear-gradient(180deg, rgb(var(--m-tertiary)) 0%, rgb(var(--m-secondary)) 100%);
  border: 1px solid rgb(var(--m-accent) / 0.08);
}

.chart-meta {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 0.75rem;
  margin-bottom: 1rem;
}

.meta-label {
  display: block;
  margin-bottom: 0.25rem;
  font-family: var(--font-mono);
  font-size: 0.68rem;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: rgb(var(--m-muted));
}

.meta-value {
  font-family: var(--font-display);
  font-size: 1.1rem;
  font-weight: 700;
  color: rgb(var(--m-text));
}

.chart-svg {
  width: 100%;
  height: 320px;
  display: block;
}

.grid-line {
  stroke: rgb(var(--m-border) / 0.35);
  stroke-width: 1;
  stroke-dasharray: 6 10;
}

.chart-line {
  fill: none;
  stroke-width: 4;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.chart-skeleton {
  width: 100%;
  height: 320px;
  border-radius: 12px;
}

@media (max-width: 820px) {
  .chart-meta {
    grid-template-columns: 1fr;
  }
}
</style>
