// charts.jsx — SVG chart components for the dashboard

function fmtKwh(v) {
  if (v >= 1000) return (v / 1000).toFixed(v >= 10000 ? 1 : 2) + 'K';
  if (v >= 100) return v.toFixed(0);
  if (v >= 10) return v.toFixed(1);
  return v.toFixed(2);
}

function niceMax(v) {
  if (v <= 0) return 1;
  const exp = Math.pow(10, Math.floor(Math.log10(v)));
  const n = v / exp;
  let step;
  if (n <= 1) step = 1;
  else if (n <= 2) step = 2;
  else if (n <= 5) step = 5;
  else step = 10;
  return step * exp;
}

// ── Bar chart for year (12 months) or month (28-31 days) ──────────
function BarChart({ data, onSelect, activeIndex, formatLabel, formatTip, height = 320 }) {
  const wrapRef = React.useRef(null);
  const [w, setW] = React.useState(900);
  const [hover, setHover] = React.useState(null);

  React.useEffect(() => {
    if (!wrapRef.current) return;
    const ro = new ResizeObserver(entries => {
      for (const e of entries) setW(e.contentRect.width);
    });
    ro.observe(wrapRef.current);
    return () => ro.disconnect();
  }, []);

  const padL = 52, padR = 18, padT = 18, padB = 38;
  const innerW = Math.max(40, w - padL - padR);
  const innerH = height - padT - padB;
  const n = data.length;
  const maxV = niceMax(Math.max(...data.map(d => d.value), 0.001));
  const ticks = 4;

  // LTR: i=0 on LEFT (near Y-axis labels), i=n-1 on RIGHT
  const slot = innerW / n;
  const barW = Math.min(slot * 0.72, 56);

  function xForIndex(i) {
    // i=0 → leftmost
    return padL + slot * i + (slot - barW) / 2;
  }

  // Hover tooltip pos
  let tip = null;
  if (hover !== null) {
    const d = data[hover];
    const cx = xForIndex(hover) + barW / 2;
    const barH = (d.value / maxV) * innerH;
    const cy = padT + innerH - barH;
    tip = (
      <div className="chart-tooltip" style={{ left: cx, top: cy }}>
        <div className="ttl">{formatTip ? formatTip(d, hover).label : d.label}</div>
        <strong>{d.value.toFixed(2)} kWh</strong>
      </div>
    );
  }

  return (
    <div className="chart-wrap" ref={wrapRef}>
      <svg className="chart-svg" viewBox={`0 0 ${w} ${height}`} preserveAspectRatio="none">
        {/* grid */}
        {Array.from({ length: ticks + 1 }).map((_, i) => {
          const y = padT + innerH - (i / ticks) * innerH;
          const v = (maxV * i) / ticks;
          return (
            <g key={i}>
              <line className="grid-line" x1={padL - 4} x2={w - padR} y1={y} y2={y} />
              <text className="axis-label" x={padL - 8} y={y + 3} textAnchor="end">{fmtKwh(v)}</text>
            </g>
          );
        })}

        {/* bars */}
        {data.map((d, i) => {
          const x = xForIndex(i);
          const barH = Math.max(2, (d.value / maxV) * innerH);
          const y = padT + innerH - barH;
          const active = i === activeIndex;
          return (
            <g
              key={i}
              className={'chart-bar' + (active ? ' active' : '')}
              onMouseEnter={() => setHover(i)}
              onMouseLeave={() => setHover(null)}
              onClick={() => onSelect && onSelect(i)}
            >
              <rect
                className="bar-rect"
                x={x}
                y={y}
                width={barW}
                height={barH}
                rx="8"
                ry="8"
              />
              <text className="bar-label" x={x + barW / 2} y={padT + innerH + 18}>
                {formatLabel ? formatLabel(d, i) : d.label}
              </text>
            </g>
          );
        })}
      </svg>
      {tip}
    </div>
  );
}

// ── Day chart: 96 intervals as a smooth area ─────────────────────
function DayChart({ intervals, height = 320, dayDate }) {
  // intervals: array of 96 {date, kwh}
  const wrapRef = React.useRef(null);
  const [w, setW] = React.useState(900);
  const [hover, setHover] = React.useState(null);

  React.useEffect(() => {
    if (!wrapRef.current) return;
    const ro = new ResizeObserver(entries => {
      for (const e of entries) setW(e.contentRect.width);
    });
    ro.observe(wrapRef.current);
    return () => ro.disconnect();
  }, []);

  const padL = 52, padR = 18, padT = 18, padB = 38;
  const innerW = Math.max(40, w - padL - padR);
  const innerH = height - padT - padB;
  const n = 96;

  const maxV = niceMax(Math.max(0.001, ...intervals.map(d => d.kwh)));
  const ticks = 4;

  // LTR: hour 0 on LEFT (near Y-axis), hour 23:45 on RIGHT
  function x(i) { return padL + (i / (n - 1)) * innerW; }

  function y(v) { return padT + innerH - (v / maxV) * innerH; }

  // determine if interval is "night" rate: Sun 23 → Mon 7, ... Thu 23 → Fri 7
  function isNight(d) {
    const dow = d.getDay(); const h = d.getHours();
    if ((dow >= 0 && dow <= 4) && h >= 23) return true;
    if ((dow >= 1 && dow <= 5) && h < 7) return true;
    return false;
  }
  function isDayRate(d) {
    const dow = d.getDay(); const h = d.getHours();
    if (dow >= 0 && dow <= 4 && h >= 7 && h < 17) return true;
    return false;
  }

  // Build area path
  const pts = intervals.map((it, i) => [x(i), y(it.kwh)]);
  const areaPath = (() => {
    if (!pts.length) return '';
    let p = `M ${pts[0][0]} ${padT + innerH} `;
    pts.forEach(([px, py]) => { p += `L ${px} ${py} `; });
    p += `L ${pts[pts.length-1][0]} ${padT + innerH} Z`;
    return p;
  })();
  const linePath = pts.length ? 'M ' + pts.map(([px, py]) => `${px} ${py}`).join(' L ') : '';

  // Day/Night bands (in chart background)
  const bands = [];
  let bandStart = null, bandKind = null;
  for (let i = 0; i < intervals.length; i++) {
    const kind = isNight(intervals[i].date) ? 'night' : (isDayRate(intervals[i].date) ? 'day' : null);
    if (kind !== bandKind) {
      if (bandStart !== null && bandKind) {
        bands.push({ kind: bandKind, from: bandStart, to: i });
      }
      bandStart = i;
      bandKind = kind;
    }
  }
  if (bandStart !== null && bandKind) bands.push({ kind: bandKind, from: bandStart, to: intervals.length });

  let tip = null;
  if (hover !== null && intervals[hover]) {
    const it = intervals[hover];
    const cx = x(hover); const cy = y(it.kwh);
    const h = it.date.getHours().toString().padStart(2, '0');
    const m = it.date.getMinutes().toString().padStart(2, '0');
    tip = (
      <div className="chart-tooltip" style={{ left: cx, top: cy }}>
        <div className="ttl">{h}:{m}</div>
        <strong>{it.kwh.toFixed(3)} kWh</strong>
      </div>
    );
  }

  // X axis labels every 3 hours
  const hourTicks = [0, 3, 6, 9, 12, 15, 18, 21];

  return (
    <div className="chart-wrap" ref={wrapRef}>
      <svg className="chart-svg" viewBox={`0 0 ${w} ${height}`} preserveAspectRatio="none">
        <defs>
          <linearGradient id="dayChartFill" x1="0" y1="0" x2="0" y2="1">
            <stop offset="0%" stopColor="oklch(0.78 0.14 55)" stopOpacity="0.55" />
            <stop offset="100%" stopColor="oklch(0.78 0.14 55)" stopOpacity="0.05" />
          </linearGradient>
          <clipPath id="dayChartClip">
            <rect x={padL} y={padT} width={innerW} height={innerH} />
          </clipPath>
        </defs>

        {/* bands */}
        <g clipPath="url(#dayChartClip)">
        {bands.map((b, idx) => {
          const xR = x(b.from);
          const xL = x(b.to - 1);
          const bx = Math.min(xR, xL);
          const bw = Math.abs(xR - xL) + (innerW / (n - 1));
          const fill = b.kind === 'day' ? 'oklch(0.95 0.045 85)' : 'oklch(0.94 0.035 260)';
          return (
            <rect key={idx} x={bx - (innerW / (n - 1)) / 2} y={padT} width={bw} height={innerH} fill={fill} opacity="0.55" />
          );
        })}
        </g>

        {/* band labels at top of chart */}
        {bands.map((b, idx) => {
          const xR = x(b.from);
          const xL = x(b.to - 1);
          const cx = (xR + xL) / 2;
          const minBw = Math.abs(xR - xL) + (innerW / (n - 1));
          if (minBw < 56) return null; // skip if too narrow
          const labelText = b.kind === 'day' ? 'תעריף יום' : 'תעריף לילה';
          const labelColor = b.kind === 'day' ? 'oklch(0.42 0.12 70)' : 'oklch(0.4 0.1 265)';
          return (
            <text
              key={'label-' + idx}
              x={cx}
              y={padT + 14}
              textAnchor="middle"
              fontSize="10.5"
              fontWeight="600"
              fill={labelColor}
              opacity="0.85"
              style={{pointerEvents:'none'}}
            >
              {labelText}
            </text>
          );
        })}

        {/* grid */}
        {Array.from({ length: ticks + 1 }).map((_, i) => {
          const yy = padT + innerH - (i / ticks) * innerH;
          const v = (maxV * i) / ticks;
          return (
            <g key={i}>
              <line className="grid-line" x1={padL - 4} x2={w - padR} y1={yy} y2={yy} />
              <text className="axis-label" x={padL - 8} y={yy + 3} textAnchor="end">{fmtKwh(v)}</text>
            </g>
          );
        })}

        {/* area */}
        <path d={areaPath} fill="url(#dayChartFill)" />
        <path d={linePath} fill="none" stroke="oklch(0.65 0.16 50)" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />

        {/* hover dots */}
        {intervals.map((it, i) => (
          <circle
            key={i}
            cx={x(i)}
            cy={y(it.kwh)}
            r={hover === i ? 4 : 2.5}
            fill={hover === i ? 'oklch(0.65 0.16 50)' : 'transparent'}
            stroke={hover === i ? 'white' : 'transparent'}
            strokeWidth="2"
            style={{ pointerEvents: 'none', transition: '0.12s ease' }}
          />
        ))}

        {/* hover capture */}
        <rect
          x={padL}
          y={padT}
          width={innerW}
          height={innerH}
          fill="transparent"
          onMouseLeave={() => setHover(null)}
          onMouseMove={(e) => {
            const rect = e.currentTarget.getBoundingClientRect();
            const mx = e.clientX - rect.left;
            // LTR: mx=0 left edge → i=0; mx=innerW right edge → i=n-1
            const ratio = mx / innerW;
            const i = Math.round(ratio * (n - 1));
            setHover(Math.max(0, Math.min(n - 1, i)));
          }}
        />

        {/* x axis labels */}
        {hourTicks.map(h => (
          <text key={h} className="axis-label" x={x(h * 4)} y={padT + innerH + 18} textAnchor="middle">
            {h.toString().padStart(2, '0')}:00
          </text>
        ))}
      </svg>
      {tip}
    </div>
  );
}

window.BarChart = BarChart;
window.DayChart = DayChart;
window.chartHelpers = { fmtKwh, niceMax };
