import { buildSeriesTooltip, getChartPalette, toNumber } from "./utils";

/**
 * Returns the primary KPI chart settings from drupalSettings.
 *
 * @return {Object}
 *   The KPI chart settings object.
 */
function getPrimaryKpiSettings() {
  return window.drupalSettings?.nativeObservabilityDashboard?.primaryKpis || {};
}

/**
 * Returns the chart payload for a specific chart id.
 *
 * @param {string} chartId
 *   The chart identifier.
 *
 * @return {Object|null}
 *   The chart payload or null.
 */
function getChartPayload(chartId) {
  const settings = getPrimaryKpiSettings();

  if (!chartId || !settings[chartId]) {
    return null;
  }

  return settings[chartId];
}

/**
 * Normalizes the chart series values.
 *
 * @param {Array} series
 *   The raw chart series.
 *
 * @return {Array}
 *   The normalized chart series.
 */
function normalizeSeries(series) {
  if (!Array.isArray(series)) {
    return [];
  }

  return series.map((item) => ({
    label: item.label || "",
    value: toNumber(item.value),
  }));
}

/**
 * Draws a sparkline chart on a canvas element.
 *
 * @param {HTMLCanvasElement} canvas
 *   The target canvas.
 * @param {Array} series
 *   The normalized chart series.
 * @param {string} colorName
 *   The semantic color name.
 */
function drawSparkline(canvas, series, colorName) {
  if (!canvas || !series.length) {
    return;
  }

  const context = canvas.getContext("2d");

  if (!context) {
    return;
  }

  const width = canvas.offsetWidth || 240;
  const height = canvas.offsetHeight || 56;

  canvas.width = width;
  canvas.height = height;

  const palette = getChartPalette(colorName);
  const values = series.map((item) => item.value);
  const minValue = Math.min(...values);
  const maxValue = Math.max(...values);
  const range = Math.max(1, maxValue - minValue);
  const stepX = values.length > 1 ? width / (values.length - 1) : width;

  context.clearRect(0, 0, width, height);

  context.beginPath();
  context.moveTo(0, height);

  values.forEach((value, index) => {
    const x = index * stepX;
    const normalized = (value - minValue) / range;
    const y = height - normalized * (height - 8) - 4;
    context.lineTo(x, y);
  });

  context.lineTo(width, height);
  context.closePath();
  context.fillStyle = palette.fill;
  context.fill();

  context.beginPath();

  values.forEach((value, index) => {
    const x = index * stepX;
    const normalized = (value - minValue) / range;
    const y = height - normalized * (height - 8) - 4;

    if (index === 0) {
      context.moveTo(x, y);
    } else {
      context.lineTo(x, y);
    }
  });

  context.strokeStyle = palette.line;
  context.lineWidth = 2;
  context.lineCap = "round";
  context.lineJoin = "round";
  context.stroke();
}

/**
 * Initializes KPI sparkline charts.
 *
 * @param {HTMLElement} container
 *   Dashboard root element.
 */
export default function initCharts(container) {
  const charts = container.querySelectorAll(".no-kpi-card__sparkline");

  charts.forEach((canvas) => {
    if (canvas.dataset.chartReady === "true") {
      return;
    }

    const chartId = canvas.dataset.chartId || "";
    const colorName = canvas.dataset.chartColor || "blue";
    const payload = getChartPayload(chartId);

    if (!payload || !Array.isArray(payload.series) || !payload.series.length) {
      return;
    }

    const series = normalizeSeries(payload.series);

    if (!series.length) {
      return;
    }

    canvas.title = buildSeriesTooltip(series, payload.unit || "");

    drawSparkline(canvas, series, colorName);
    canvas.dataset.chartReady = "true";
  });
}
