/**
 * Minimal dependency-free chart helpers for the Enterprise UI.
 * Reads colors from the enterprise.css theme variables so charts always match dark theme.
 */
window.SpCharts = (function () {
  const PAD = { top: 26, right: 12, bottom: 24, left: 36 };

  function cssVar(name, fallback) {
    const v = getComputedStyle(document.documentElement).getPropertyValue(name).trim();
    return v || fallback;
  }

  function setupCanvas(canvas) {
    const ctx = canvas.getContext('2d');
    const w = canvas.width;
    const h = canvas.height;
    ctx.clearRect(0, 0, w, h);
    return { ctx, w, h };
  }

  function niceMax(value) {
    if (!isFinite(value) || value <= 0) return 10;
    const pow = Math.pow(10, Math.floor(Math.log10(value)));
    const n = value / pow;
    let niced;
    if (n <= 1) niced = 1;
    else if (n <= 2) niced = 2;
    else if (n <= 5) niced = 5;
    else niced = 10;
    return niced * pow;
  }

  function drawEmpty(ctx, w, h) {
    ctx.fillStyle = cssVar('--muted', '#8b9aab');
    ctx.font = '12px "IBM Plex Sans", sans-serif';
    ctx.textAlign = 'center';
    ctx.textBaseline = 'middle';
    ctx.fillText('Keine Daten', w / 2, h / 2);
  }

  function drawGrid(ctx, w, h, yMax, unit) {
    const line = cssVar('--line', '#2c3a4d');
    const muted = cssVar('--muted', '#8b9aab');

    ctx.strokeStyle = line;
    ctx.lineWidth = 1;
    ctx.beginPath();
    ctx.moveTo(PAD.left, h - PAD.bottom);
    ctx.lineTo(w - PAD.right, h - PAD.bottom);
    ctx.stroke();

    ctx.font = '11px "IBM Plex Sans", sans-serif';
    ctx.textAlign = 'right';
    ctx.textBaseline = 'middle';
    const steps = 4;
    for (let i = 0; i <= steps; i++) {
      const v = (yMax / steps) * i;
      const y = h - PAD.bottom - (v / yMax) * (h - PAD.top - PAD.bottom);
      ctx.strokeStyle = 'rgba(255,255,255,0.05)';
      ctx.beginPath();
      ctx.moveTo(PAD.left, y);
      ctx.lineTo(w - PAD.right, y);
      ctx.stroke();
      ctx.fillStyle = muted;
      ctx.fillText(Math.round(v) + (unit || ''), PAD.left - 6, y);
    }
  }

  function drawXLabels(ctx, w, h, labels) {
    if (!labels || !labels.length) return;
    ctx.fillStyle = cssVar('--muted', '#8b9aab');
    ctx.font = '11px "IBM Plex Sans", sans-serif';
    ctx.textAlign = 'center';
    ctx.textBaseline = 'top';
    const usable = w - PAD.left - PAD.right;
    const maxTicks = Math.max(2, Math.floor(usable / 70));
    const step = Math.max(1, Math.ceil(labels.length / maxTicks));
    for (let i = 0; i < labels.length; i += step) {
      const x = labels.length <= 1 ? PAD.left + usable / 2 : PAD.left + (i / (labels.length - 1)) * usable;
      ctx.fillText(labels[i], x, h - PAD.bottom + 6);
    }
  }

  function drawLegend(ctx, w, series) {
    let x = PAD.left;
    const y = 12;
    ctx.font = '600 11px "IBM Plex Sans", sans-serif';
    ctx.textBaseline = 'middle';
    ctx.textAlign = 'left';
    series.forEach(s => {
      ctx.fillStyle = s.color;
      ctx.fillRect(x, y - 3, 12, 4);
      x += 16;
      ctx.fillStyle = cssVar('--text', '#edf2f7');
      ctx.fillText(s.label, x, y);
      x += ctx.measureText(s.label).width + 18;
    });
  }

  function xFor(i, n, w) {
    const usable = w - PAD.left - PAD.right;
    return n <= 1 ? PAD.left + usable / 2 : PAD.left + (i / (n - 1)) * usable;
  }

  function yFor(v, yMax, h) {
    const usable = h - PAD.top - PAD.bottom;
    return h - PAD.bottom - (Math.max(0, Number(v) || 0) / yMax) * usable;
  }

  /**
   * Multi-line chart with optional legend.
   * series: [{ label, color, values: number[] }]
   * options: { labels: string[], unit, yMax, legend, points }
   */
  function drawLineChart(canvas, series, options = {}) {
    if (!canvas) return;
    const { ctx, w, h } = setupCanvas(canvas);
    series = series || [];
    const allValues = series.flatMap(s => s.values || []).filter(v => v != null);
    const yMax = options.yMax || niceMax(Math.max(1, ...allValues, 0));

    drawGrid(ctx, w, h, yMax, options.unit);
    drawXLabels(ctx, w, h, options.labels);

    series.forEach(s => {
      const values = s.values || [];
      if (!values.length) return;
      ctx.strokeStyle = s.color;
      ctx.lineWidth = 2;
      ctx.beginPath();
      values.forEach((v, i) => {
        if (v == null) return;
        const x = xFor(i, values.length, w);
        const y = yFor(v, yMax, h);
        if (i === 0) ctx.moveTo(x, y); else ctx.lineTo(x, y);
      });
      ctx.stroke();

      if (options.points !== false) {
        ctx.fillStyle = s.color;
        values.forEach((v, i) => {
          if (v == null) return;
          ctx.beginPath();
          ctx.arc(xFor(i, values.length, w), yFor(v, yMax, h), 2, 0, Math.PI * 2);
          ctx.fill();
        });
      }
    });

    if (options.legend !== false && series.length) drawLegend(ctx, w, series);
    if (!allValues.length) drawEmpty(ctx, w, h);
  }

  /**
   * Stacked area chart (e.g. Critical + Warning counts).
   * series: [{ label, color, values: number[] }]
   */
  function drawStackedArea(canvas, series, options = {}) {
    if (!canvas) return;
    const { ctx, w, h } = setupCanvas(canvas);
    series = series || [];
    const n = (series[0] && series[0].values || []).length;
    const totals = [];
    for (let i = 0; i < n; i++) {
      totals.push(series.reduce((sum, s) => sum + (Number((s.values || [])[i]) || 0), 0));
    }
    const yMax = options.yMax || niceMax(Math.max(1, ...totals, 0));

    drawGrid(ctx, w, h, yMax, options.unit);
    drawXLabels(ctx, w, h, options.labels);

    const cumulative = new Array(n).fill(0);
    series.forEach(s => {
      const values = s.values || [];
      const topPts = [];
      const basePts = [];
      for (let i = 0; i < n; i++) {
        const x = xFor(i, n, w);
        const base = cumulative[i];
        const top = base + (Number(values[i]) || 0);
        basePts.push({ x, y: yFor(base, yMax, h) });
        topPts.push({ x, y: yFor(top, yMax, h) });
        cumulative[i] = top;
      }

      if (topPts.length) {
        ctx.beginPath();
        topPts.forEach((p, i) => i === 0 ? ctx.moveTo(p.x, p.y) : ctx.lineTo(p.x, p.y));
        for (let i = basePts.length - 1; i >= 0; i--) ctx.lineTo(basePts[i].x, basePts[i].y);
        ctx.closePath();
        ctx.fillStyle = s.color + '4d';
        ctx.fill();

        ctx.strokeStyle = s.color;
        ctx.lineWidth = 1.5;
        ctx.beginPath();
        topPts.forEach((p, i) => i === 0 ? ctx.moveTo(p.x, p.y) : ctx.lineTo(p.x, p.y));
        ctx.stroke();
      }
    });

    if (options.legend !== false && series.length) drawLegend(ctx, w, series);
    if (!n || !totals.some(v => v > 0)) {
      if (!n) drawEmpty(ctx, w, h);
    }
  }

  return { drawLineChart, drawStackedArea, cssVar };
})();
