<template>
  <Teleport to="body" v-if="visible">
    <div
      class="price-history-popup panel p-4 shadow-lg"
      :style="popupStyle"
      @mouseenter="keepOpen"
      @mouseleave="close"
    >
      <div class="flex items-center justify-between mb-2">
        <div class="section-title text-sm">Historique 30j</div>
      </div>
      <svg class="w-full h-12 mb-2" viewBox="0 0 120 40" preserveAspectRatio="none">
        <polyline
          :points="polyPoints"
          class="sparkline"
          fill="none"
        />
        <circle
          v-for="(point, index) in svgPoints"
          :key="`history-point-${index}`"
          :cx="point.cx"
          :cy="point.cy"
          r="1.2"
          stroke="currentColor"
          fill="currentColor"
        />
      </svg>
      <div class="grid grid-cols-2 gap-3 text-[0.75rem]">
        <div>Actuel<br /><strong>{{ formatPrice(currentPrice) }}</strong></div>
        <div>Min<br /><strong>{{ formatPrice(minPrice) }}</strong></div>
        <div>Max<br /><strong>{{ formatPrice(maxPrice) }}</strong></div>
        <div>Delta<br /><strong>{{ deltaLabel }}</strong></div>
      </div>
    </div>
  </Teleport>
</template>

<script setup lang="ts">
import { computed } from "vue";

const props = defineProps({
  visible: Boolean,
  position: {
    type: Object,
    default: () => ({ top: 0, left: 0 }),
  },
  history: {
    type: Array,
    default: () => [],
  },
  currentPrice: {
    type: Number,
    default: 0,
  },
  minPrice: {
    type: Number,
    default: 0,
  },
  maxPrice: {
    type: Number,
    default: 0,
  },
  delta: {
    type: Number,
    default: 0,
  },
});

const formattedDelta = computed(() => {
  const value = Number(props.delta ?? 0);
  if (!Number.isFinite(value) || value === 0) {
    return "—";
  }
  const arrow = value > 0 ? "▲" : "▼";
  return `${arrow} ${Math.abs(value).toFixed(1)}%`;
});

const polyPoints = computed(() => {
  if (!props.history.length) {
    return "0,30 30,20 60,15 90,25 120,20";
  }
  const max = Math.max(...props.history);
  const min = Math.min(...props.history);
  const range = max - min || 1;
  return props.history
    .map((value, index) => {
      const x = (index / (props.history.length - 1 || 1)) * 120;
      const y = 40 - ((value - min) / range) * 40;
      return `${x.toFixed(1)},${y.toFixed(1)}`;
    })
    .join(" ");
});

const svgPoints = computed(() => {
  if (!props.history.length) {
    return [];
  }
  const max = Math.max(...props.history);
  const min = Math.min(...props.history);
  const range = max - min || 1;
  return props.history.map((value, index) => {
    const x = (index / (props.history.length - 1 || 1)) * 120;
    const y = 40 - ((value - min) / range) * 40;
    return { cx: x.toFixed(1), cy: y.toFixed(1) };
  });
});

const emit = defineEmits<{
  (event: "mouseenter"): void;
  (event: "mouseleave"): void;
}>();

const popupStyle = computed(() => ({
  position: "fixed",
  top: `${props.position.top}px`,
  left: `${props.position.left}px`,
  width: "280px",
  zIndex: 50,
}));
const deltaLabel = formattedDelta;

const formatPrice = (value: number) => {
  if (!Number.isFinite(value)) {
    return "n/a";
  }
  return `${value.toFixed(2)} €`;
};

function keepOpen() {
  emit("mouseenter");
}

function close() {
  emit("mouseleave");
}
</script>
