// 1Radar v3 — Shared chart utilities

const MONTHS_SHORT = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];

// Generate n pseudo-random data points with organic-looking variance around base
const genDailyData = (seed, base, n = 30) => {
  const s = seed % 1000;
  return Array.from({ length: n }, (_, i) => {
    const t     = i / Math.max(1, n - 1);
    const wave1 = Math.sin(s / 159 + i * 0.71) * 0.18;
    const wave2 = Math.sin(s / 97  + i * 1.57) * 0.10;
    const rand  = (((s + i * 29) % 100) / 100 - 0.5) * 0.10;
    const trend = t * 0.12;
    return Math.max(0, base * (1 + wave1 + wave2 + rand + trend));
  });
};

// "May 11", "May 12", … for the last n days
const genDayLabels = (n = 30) => {
  const now = new Date();
  return Array.from({ length: n }, (_, i) => {
    const d = new Date(now);
    d.setDate(d.getDate() - (n - 1 - i));
    return `${MONTHS_SHORT[d.getMonth()]} ${d.getDate()}`;
  });
};

// Last 6 months: "Dec", "Jan", …
const genMonthLabels = () => {
  const now = new Date();
  return Array.from({ length: 6 }, (_, i) => {
    const d = new Date(now.getFullYear(), now.getMonth() - 5 + i, 1);
    return MONTHS_SHORT[d.getMonth()];
  });
};

// Pre-compute stable label arrays (good for the session lifetime)
const DAY_LABELS_30  = genDayLabels(30);
const MONTH_LABELS_6 = genMonthLabels();

// ── MiniAreaChart ─────────────────────────────────────────────────────────────
// Props:
//   data      — number[]
//   labels    — string[] (same length), shown as x-axis label in tooltip
//   formatY   — (v: number) => string, formats the y value in the tooltip
//   width     — fixed pixel width; omit / pass undefined for 100% block width
//   height    — pixel height (default 28)
//   color     — stroke/fill color (default var(--accent))
//   minZero   — whether the y-axis floor is always 0
let _macSeq = 0;

const MiniAreaChart = ({ data, labels, formatY, width, height = 28, color = 'var(--accent)', minZero = false }) => {
  const [uid]   = React.useState(() => `mac${++_macSeq}`);
  const [hover, setHover] = React.useState(null);

  if (!data || data.length < 2) return null;

  const VW    = 400; // internal viewBox width — preserveAspectRatio=none will stretch it
  const yMin  = minZero ? 0 : Math.min(...data);
  const yMax  = Math.max(...data);
  const yRange = yMax - yMin || 1;

  // Returns pixel-Y relative to the top of the SVG (same scale as viewBox height)
  const getPY = (v) => height - ((v - yMin) / yRange) * (height * 0.88) - height * 0.06;

  const pts      = data.map((v, i) => ({ x: (i / (data.length - 1)) * VW, y: getPY(v) }));
  const linePath = pts.map((p, i) => `${i === 0 ? 'M' : 'L'}${p.x.toFixed(2)},${p.y.toFixed(2)}`).join(' ');
  const areaPath = `${linePath} L${pts[pts.length-1].x.toFixed(2)},${height} L0,${height} Z`;

  const onMouseMove = (e) => {
    const rect = e.currentTarget.getBoundingClientRect();
    const relX  = Math.max(0, Math.min(1, (e.clientX - rect.left) / rect.width));
    const idx   = Math.round(relX * (data.length - 1));
    setHover({ idx, relX: idx / (data.length - 1), cx: e.clientX, cy: e.clientY });
  };

  const isFixed = !!width;
  const dotPY   = hover !== null ? getPY(data[hover.idx]) : null;

  return (
    <div style={{ position: 'relative', display: isFixed ? 'inline-block' : 'block', width: isFixed ? width : '100%' }}>
      <svg
        viewBox={`0 0 ${VW} ${height}`}
        width={isFixed ? width : '100%'}
        height={height}
        style={{ display: 'block', cursor: 'crosshair' }}
        preserveAspectRatio="none"
        onMouseMove={onMouseMove}
        onMouseLeave={() => setHover(null)}
      >
        <defs>
          <linearGradient id={uid} x1="0" y1="0" x2="0" y2="1">
            <stop offset="0%"   stopColor={color} stopOpacity="0.22"/>
            <stop offset="100%" stopColor={color} stopOpacity="0.02"/>
          </linearGradient>
        </defs>
        <path d={areaPath} fill={`url(#${uid})`}/>
        <path d={linePath} fill="none" stroke={color} strokeWidth="1.6"
              vectorEffect="non-scaling-stroke" strokeLinejoin="round" strokeLinecap="round"/>
      </svg>

      {hover !== null && <>
        {/* Vertical cursor line */}
        <div style={{
          position: 'absolute', top: 0, bottom: 0,
          left: `${hover.relX * 100}%`,
          width: 1, background: color, opacity: 0.35,
          pointerEvents: 'none', transform: 'translateX(-0.5px)',
        }}/>
        {/* Hover dot — positioned in pixel-space, avoids SVG scaling distortion */}
        <div style={{
          position: 'absolute',
          left: `${hover.relX * 100}%`,
          top: dotPY,
          width: 7, height: 7, borderRadius: 999,
          transform: 'translate(-50%, -50%)',
          background: color,
          border: '1.5px solid var(--bg-surface)',
          pointerEvents: 'none',
        }}/>
        {/* Tooltip — fixed so it escapes any overflow clipping */}
        <div style={{
          position: 'fixed',
          left: hover.cx + 14,
          top: hover.cy - 52,
          background: 'var(--bg-surface)',
          border: '1px solid var(--border)',
          borderRadius: 8,
          padding: '5px 9px',
          fontFamily: 'var(--font-mono)',
          boxShadow: '0 6px 20px rgba(14,18,27,0.14)',
          zIndex: 9999,
          pointerEvents: 'none',
          whiteSpace: 'nowrap',
          display: 'flex', flexDirection: 'column', gap: 2,
        }}>
          {labels && <span style={{ color: 'var(--text-faint)', fontSize: 10 }}>{labels[hover.idx]}</span>}
          <span style={{ fontWeight: 600, color: 'var(--text)', fontSize: 12 }}>
            {formatY ? formatY(data[hover.idx]) : data[hover.idx].toLocaleString()}
          </span>
        </div>
      </>}
    </div>
  );
};

Object.assign(window, { MONTHS_SHORT, genDailyData, genDayLabels, genMonthLabels, DAY_LABELS_30, MONTH_LABELS_6, MiniAreaChart });
