/* ═══════════════════════════════════════════════════════════════════
   DASHBOARD HERO CHART · BTC/USDT premium candles + RSI
   Includes coin header strip on top + chart + RSI subpanel
   ═══════════════════════════════════════════════════════════════════ */

function HeroChart({ coin, live, candles, ema21, ema55, vwap, rsi, orders, supportZones, resistanceZones }) {
  /* The chart body is the shared pro engine (st-chart.jsx): live data per
     timeframe, wheel zoom, drag pan, real time axis. The premium header
     strip stays exactly as it was. */
  return (
    <div style={{
      background: ST.bg2,
      border: `1px solid ${ST.border}`,
      borderRadius: 12,
      overflow: 'hidden',
      display: 'flex', flexDirection: 'column',
      minHeight: 0, flex: 1,
      boxShadow: 'inset 0 1px 0 rgba(255,255,255,0.02)',
    }}>
      <CoinHeaderStrip coin={coin} live={live} />
      <STProChart
        sym={coin.sym}
        orders={orders}
        supportZones={supportZones}
        resistanceZones={resistanceZones}
        defaultTf="15m"
      />
    </div>
  );
}

/* ═══════════════════════════════════════════════════════════════════
   Coin header strip (within chart card top)
   ═══════════════════════════════════════════════════════════════════ */
function CoinHeaderStrip({ coin, live }) {
  const up = live.chg >= 0;
  return (
    <div style={{
      padding: '14px 18px',
      borderBottom: `1px solid ${ST.border}`,
      background: `radial-gradient(ellipse 600px 120px at 20% 50%, rgba(247,166,0,0.05) 0%, transparent 70%), ${ST.bg2}`,
      display: 'flex', alignItems: 'center', gap: 18,
      flexShrink: 0,
    }}>
      <CoinGlyph sym={coin.sym} size={40} />
      <div>
        <div style={{ display: 'flex', alignItems: 'baseline', gap: 8 }}>
          <span style={{ fontSize: 16, fontWeight: 600, color: ST.ink, letterSpacing: '-0.01em' }}>
            {coin.name}
          </span>
          <span className="mono" style={{ fontSize: 11, color: ST.ink3 }}>
            {coin.sym}/USDT
          </span>
          <GroupPill group={coin.group} />
        </div>
        <div className="mono" style={{ fontSize: 9, color: ST.ink4, marginTop: 3, letterSpacing: '0.08em' }}>
          RANK #{coin.rank} · MCAP <span style={{ color: ST.ink2 }}>$2.07T</span>
        </div>
      </div>

      <div style={{ display: 'flex', alignItems: 'baseline', gap: 12, marginLeft: 6 }}>
        <span className="num" style={{
          fontSize: 32, fontWeight: 500, color: ST.ink,
          letterSpacing: '-0.02em', lineHeight: 1,
        }}>${ST_fmt.price(live.price)}</span>
        <div style={{
          display: 'flex', alignItems: 'center', gap: 5,
          padding: '4px 8px', borderRadius: 4,
          background: up ? ST.greenFog : ST.redFog,
          border: `1px solid ${up ? ST.green + '40' : ST.red + '40'}`,
        }}>
          <svg width="9" height="9" viewBox="0 0 10 10">
            <path d={up ? 'M 5 2 L 9 7 L 1 7 Z' : 'M 5 8 L 1 3 L 9 3 Z'}
              fill={up ? ST.green : ST.red} />
          </svg>
          <span className="num" style={{ fontSize: 12, color: up ? ST.green : ST.red, fontWeight: 600 }}>
            {ST_fmt.pct(live.chg, 2)}
          </span>
        </div>
      </div>

      {/* 24h range bar — fills the empty middle */}
      <div style={{ flex: 1, display: 'flex', justifyContent: 'center', minWidth: 0, paddingLeft: 24 }}>
        <RangeBar24h low={live.low} high={live.high} price={live.price} />
      </div>

      <div style={{ display: 'flex', gap: 22, alignItems: 'baseline' }}>
        <KvInline k="24H HIGH"  v={`$${ST_fmt.price(live.high)}`} />
        <KvInline k="24H LOW"   v={`$${ST_fmt.price(live.low)}`} />
        <KvInline k="VOL 24H"   v={`$${live.vol.toFixed(1)}B`} />
        <KvInline k="LAST"      v={live.lastTs} c={ST.amber} />
      </div>
    </div>
  );
}

function KvInline({ k, v, c }) {
  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 1 }}>
      <span className="eyebrow" style={{ fontSize: 9 }}>{k}</span>
      <span className="num" style={{ fontSize: 12, color: c || ST.ink2, fontWeight: 500 }}>{v}</span>
    </div>
  );
}

/* ── 24h range bar — where the live price sits in the day's low→high ──── */
function RangeBar24h({ low, high, price }) {
  const lo = parseFloat(low) || 0, hi = parseFloat(high) || 0, p = parseFloat(price) || 0;
  const range = hi - lo;
  const pct = range > 0 ? Math.max(0, Math.min(100, (p - lo) / range * 100)) : 50;
  const near = pct >= 66 ? ST.green : pct <= 33 ? ST.red : ST.amber;
  const label = pct >= 66 ? 'near high' : pct <= 33 ? 'near low' : 'mid-range';
  return (
    <div style={{ width: '100%', maxWidth: 340 }}>
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline', marginBottom: 5 }}>
        <span className="eyebrow" style={{ fontSize: 8 }}>24H RANGE</span>
        <span className="mono" style={{ fontSize: 9, fontWeight: 600, color: near }}>{pct.toFixed(0)}% · {label}</span>
      </div>
      <div style={{ position: 'relative', height: 5, borderRadius: 3,
        background: `linear-gradient(90deg, ${ST.red}44, ${ST.amber}44, ${ST.green}44)` }}>
        <div style={{ position: 'absolute', left: `${pct}%`, top: -3, bottom: -3, width: 3,
          background: ST.ink, borderRadius: 2, transform: 'translateX(-50%)', boxShadow: `0 0 6px ${near}` }} />
      </div>
      <div style={{ display: 'flex', justifyContent: 'space-between', marginTop: 4 }}>
        <span className="num" style={{ fontSize: 9, color: ST.ink4 }}>${ST_fmt.price(lo)}</span>
        <span className="num" style={{ fontSize: 9, color: ST.ink4 }}>${ST_fmt.price(hi)}</span>
      </div>
    </div>
  );
}

function ChartLegendItem({ color, dash, label, value }) {
  return (
    <div style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
      <svg width="14" height="6">
        <line x1="0" y1="3" x2="14" y2="3"
          stroke={color} strokeWidth="1.5"
          strokeDasharray={dash ? '2 2' : undefined} />
      </svg>
      <span className="mono" style={{ fontSize: 10, color: ST.ink3, fontWeight: 500 }}>{label}</span>
      <span className="num" style={{ fontSize: 11, color, fontWeight: 600 }}>{value}</span>
    </div>
  );
}

function ChartIconBtn({ icon, active }) {
  return (
    <button style={{
      width: 24, height: 24, borderRadius: 4,
      background: active ? `${ST.amber}1A` : 'transparent',
      border: `1px solid ${active ? ST.amber + '40' : ST.border}`,
      color: active ? ST.amber : ST.ink3,
      cursor: 'pointer', display: 'grid', placeItems: 'center', padding: 0,
    }}>
      <svg width="14" height="14" viewBox="0 0 16 16" fill="none">{icon}</svg>
    </button>
  );
}

/* ─── The chart SVG ──────────────────────────────────────────────── */
function ChartSvg({ candles, orders, supportZones, resistanceZones, ema21, ema55, vwap, rsi, hover, setHover }) {
  const W = 900, H = 560;
  const PADL = 14, PADR = 78, PADT = 10;
  const PRICE_H = 400;
  const VOL_H   = 38;
  const RSI_H   = 90;
  const GAP     = 10;

  const priceTop = PADT;
  const priceBot = priceTop + PRICE_H;
  const volTop   = priceBot + 4;
  const volBot   = volTop + VOL_H;
  const rsiTop   = volBot + GAP;
  const rsiBot   = rsiTop + RSI_H;

  // price scale — include candles, orders, and S/R zones so they're all visible
  const extraPrices = [
    ...orders.map(o => o.price),
    ...supportZones.flatMap(z => [z.lo, z.hi]),
    ...resistanceZones.flatMap(z => [z.lo, z.hi]),
  ];
  const hi = Math.max(...candles.map(c => c.h), ...extraPrices);
  const lo = Math.min(...candles.map(c => c.l), ...extraPrices);
  const pad = (hi - lo) * 0.08;
  const PMAX = hi + pad, PMIN = lo - pad;
  const Y = (p) => priceTop + (PRICE_H * (PMAX - p) / (PMAX - PMIN));

  // x scale
  const innerW = W - PADL - PADR;
  const cw = innerW / candles.length;
  const X = (i) => PADL + i * cw + cw / 2;

  // gridlines
  const gridYs = [];
  const step = (PMAX - PMIN) / 5;
  for (let i = 1; i < 5; i++) gridYs.push(PMIN + step * i);

  // volume scale
  const vMax = Math.max(...candles.map(c => c.v));
  const Yv = (v) => volBot - (VOL_H * v / vMax);

  // RSI scale
  const Yrsi = (r) => rsiTop + (RSI_H * (100 - r) / 100);

  const lastPrice = candles[candles.length - 1].c;
  const lastRsi = rsi[rsi.length - 1];

  const fmtP = (p) => p.toLocaleString('en-US', { maximumFractionDigits: 0 });

  return (
    <svg viewBox={`0 0 ${W} ${H}`} preserveAspectRatio="none"
      width="100%" height="100%"
      onMouseMove={(e) => {
        const rect = e.currentTarget.getBoundingClientRect();
        const sx = (e.clientX - rect.left) * (W / rect.width);
        const sy = (e.clientY - rect.top)  * (H / rect.height);
        const idx = Math.max(0, Math.min(candles.length - 1, Math.floor((sx - PADL) / cw)));
        setHover({ x: sx, y: sy, idx });
      }}
      onMouseLeave={() => setHover(null)}
      style={{ display: 'block' }}
    >
      {/* ── background gridlines ── */}
      {gridYs.map((p, i) => (
        <line key={i} x1={PADL} x2={W - PADR} y1={Y(p)} y2={Y(p)}
          stroke={ST.grid} strokeWidth="1" />
      ))}
      {Array.from({ length: 7 }).map((_, i) => {
        const x = PADL + (i / 6) * innerW;
        return <line key={i} x1={x} x2={x} y1={priceTop} y2={priceBot}
          stroke={ST.grid} strokeWidth="1" />;
      })}

      {/* ── support / resistance zones ── */}
      {resistanceZones.map((z, i) => (
        <g key={`r${i}`}>
          <rect x={PADL} width={innerW}
            y={Y(z.hi)} height={Y(z.lo) - Y(z.hi)}
            fill={ST.red} opacity="0.08" />
          <line x1={PADL} x2={W - PADR} y1={Y(z.hi)} y2={Y(z.hi)}
            stroke={ST.red} strokeWidth="0.8" strokeDasharray="2 4" opacity="0.6" />
          <line x1={PADL} x2={W - PADR} y1={Y(z.lo)} y2={Y(z.lo)}
            stroke={ST.red} strokeWidth="0.8" strokeDasharray="2 4" opacity="0.6" />
          <text x={PADL + 6} y={Y(z.hi) - 4}
            fontFamily="JetBrains Mono" fontSize="9" fill={ST.red} opacity="0.9">
            RESISTANCE · ${fmtP(z.lo)}–${fmtP(z.hi)}
          </text>
        </g>
      ))}
      {supportZones.map((z, i) => (
        <g key={`s${i}`}>
          <rect x={PADL} width={innerW}
            y={Y(z.hi)} height={Y(z.lo) - Y(z.hi)}
            fill={ST.green} opacity="0.08" />
          <line x1={PADL} x2={W - PADR} y1={Y(z.hi)} y2={Y(z.hi)}
            stroke={ST.green} strokeWidth="0.8" strokeDasharray="2 4" opacity="0.6" />
          <line x1={PADL} x2={W - PADR} y1={Y(z.lo)} y2={Y(z.lo)}
            stroke={ST.green} strokeWidth="0.8" strokeDasharray="2 4" opacity="0.6" />
          <text x={PADL + 6} y={Y(z.lo) - 4}
            fontFamily="JetBrains Mono" fontSize="9" fill={ST.green} opacity="0.9">
            SUPPORT · ${fmtP(z.lo)}–${fmtP(z.hi)}
          </text>
        </g>
      ))}

      {/* ── EMA 21 ── */}
      <path d={candles.map((_, i) => `${i === 0 ? 'M' : 'L'} ${X(i)} ${Y(ema21[i])}`).join(' ')}
        stroke={ST.amber} strokeWidth="1.5" fill="none" opacity="0.9" />
      {/* ── EMA 55 ── */}
      <path d={candles.map((_, i) => `${i === 0 ? 'M' : 'L'} ${X(i)} ${Y(ema55[i])}`).join(' ')}
        stroke={ST.blue} strokeWidth="1.5" fill="none" opacity="0.9" />
      {/* ── VWAP ── */}
      <path d={candles.map((_, i) => `${i === 0 ? 'M' : 'L'} ${X(i)} ${Y(vwap[i])}`).join(' ')}
        stroke={ST.ink2} strokeWidth="1.2" strokeDasharray="3 3" fill="none" opacity="0.7" />

      {/* ── Candles ── */}
      {candles.map((c, i) => {
        const up = c.c >= c.o;
        const col = up ? ST.green : ST.red;
        const bodyTop = Y(Math.max(c.o, c.c));
        const bodyBot = Y(Math.min(c.o, c.c));
        const bodyH = Math.max(1, bodyBot - bodyTop);
        const bw = Math.max(1, cw * 0.7);
        return (
          <g key={i} opacity="0.95">
            <line x1={X(i)} x2={X(i)} y1={Y(c.h)} y2={Y(c.l)}
              stroke={col} strokeWidth="1" />
            <rect x={X(i) - bw/2} y={bodyTop} width={bw} height={bodyH}
              fill={col} opacity={up ? 0.5 : 0.9} />
            {!up && <rect x={X(i) - bw/2} y={bodyTop} width={bw} height={bodyH}
              fill="none" stroke={col} strokeWidth="0.8" />}
          </g>
        );
      })}

      {/* ── Volume bars ── */}
      {candles.map((c, i) => {
        const up = c.c >= c.o;
        const col = up ? ST.green : ST.red;
        const bw = Math.max(1, cw * 0.7);
        return (
          <rect key={`v${i}`}
            x={X(i) - bw/2} y={Yv(c.v)}
            width={bw} height={volBot - Yv(c.v)}
            fill={col} opacity="0.35" />
        );
      })}

      {/* ── Order lines (amber dotted) ── */}
      {orders.map((o, i) => {
        const y = Y(o.price);
        const c = o.verdict === 'GOOD' ? ST.green : o.verdict === 'AVOID' ? ST.red : ST.amber;
        return (
          <g key={i}>
            <line x1={PADL} x2={W - PADR} y1={y} y2={y}
              stroke={c} strokeWidth="1" strokeDasharray="6 4" opacity="0.85" />
            <rect x={W - PADR + 4} y={y - 7.5} width={70} height={15}
              fill={c} rx="2" />
            <text x={W - PADR + 39} y={y + 3.5}
              fontFamily="JetBrains Mono" fontSize="9" fontWeight="700"
              textAnchor="middle" fill="#0B0D14">
              ${fmtP(o.price)}
            </text>
            <text x={PADL + 8} y={y - 4}
              fontFamily="JetBrains Mono" fontSize="9" fontWeight="600"
              fill={c}>
              BUY · {o.qty.toFixed(4)} BTC · {o.verdict}
            </text>
          </g>
        );
      })}

      {/* ── Last price line + label ── */}
      <line x1={PADL} x2={W - PADR} y1={Y(lastPrice)} y2={Y(lastPrice)}
        stroke={ST.amber} strokeWidth="0.6" strokeDasharray="1 2" opacity="0.6" />
      <rect x={W - PADR + 4} y={Y(lastPrice) - 8} width={70} height={16}
        fill={ST.amber} rx="2" />
      <text x={W - PADR + 39} y={Y(lastPrice) + 4}
        fontFamily="JetBrains Mono" fontSize="10" fontWeight="700"
        textAnchor="middle" fill="#0B0D14">
        ${fmtP(lastPrice)}
      </text>

      {/* ── Price axis labels ── */}
      {gridYs.map((p, i) => (
        <text key={`pa${i}`} x={W - PADR + 4} y={Y(p) + 3}
          fontFamily="JetBrains Mono" fontSize="9" fill={ST.ink3}>
          {fmtP(p)}
        </text>
      ))}

      {/* ── Volume label ── */}
      <text x={PADL} y={volTop - 2}
        fontFamily="JetBrains Mono" fontSize="8" fill={ST.ink4} letterSpacing="0.1em">VOLUME</text>

      {/* ── RSI subpanel ── */}
      <g>
        <rect x={PADL} y={rsiTop} width={innerW} height={RSI_H}
          fill="rgba(255,255,255,0.015)" />
        <line x1={PADL} x2={W - PADR} y1={Yrsi(70)} y2={Yrsi(70)}
          stroke={ST.red} strokeDasharray="2 4" strokeWidth="0.8" opacity="0.6" />
        <line x1={PADL} x2={W - PADR} y1={Yrsi(30)} y2={Yrsi(30)}
          stroke={ST.green} strokeDasharray="2 4" strokeWidth="0.8" opacity="0.6" />
        <line x1={PADL} x2={W - PADR} y1={Yrsi(50)} y2={Yrsi(50)}
          stroke={ST.ink5} strokeWidth="0.5" opacity="0.6" />

        <text x={W - PADR + 4} y={Yrsi(70) + 3} fontFamily="JetBrains Mono" fontSize="9" fill={ST.red} opacity="0.8">70</text>
        <text x={W - PADR + 4} y={Yrsi(30) + 3} fontFamily="JetBrains Mono" fontSize="9" fill={ST.green} opacity="0.8">30</text>
        <text x={PADL + 4} y={rsiTop + 12}
          fontFamily="JetBrains Mono" fontSize="9" fill={ST.amber} letterSpacing="0.1em" fontWeight="700">RSI · 14</text>
        <text x={PADL + 64} y={rsiTop + 12}
          fontFamily="JetBrains Mono" fontSize="9" fill={ST.ink3}>
          current <tspan fill={lastRsi > 70 ? ST.red : lastRsi < 30 ? ST.green : ST.ink} fontWeight="700">{lastRsi.toFixed(1)}</tspan>
        </text>

        {/* rsi line */}
        <path d={rsi.map((r, i) => `${i === 0 ? 'M' : 'L'} ${X(i)} ${Yrsi(r)}`).join(' ')}
          stroke={ST.amber} strokeWidth="1.5" fill="none" />

        {/* current rsi value */}
        <rect x={W - PADR + 4} y={Yrsi(lastRsi) - 8} width={70} height={16}
          fill={ST.amber} rx="2" />
        <text x={W - PADR + 39} y={Yrsi(lastRsi) + 4}
          fontFamily="JetBrains Mono" fontSize="10" fontWeight="700"
          textAnchor="middle" fill="#0B0D14">
          {lastRsi.toFixed(1)}
        </text>
      </g>

      {/* ── Crosshair ── */}
      {hover && hover.x > PADL && hover.x < W - PADR && (
        <g style={{ pointerEvents: 'none' }}>
          <line x1={hover.x} x2={hover.x} y1={priceTop} y2={rsiBot}
            stroke={ST.ink3} strokeWidth="0.5" strokeDasharray="2 3" opacity="0.6" />
          <line x1={PADL} x2={W - PADR} y1={hover.y} y2={hover.y}
            stroke={ST.ink3} strokeWidth="0.5" strokeDasharray="2 3" opacity="0.6" />
          {/* tooltip */}
          {hover.y >= priceTop && hover.y <= priceBot && (() => {
            const c = candles[hover.idx];
            const tooltipX = hover.x > W / 2 ? PADL + 8 : W - PADR - 162;
            return (
              <g>
                <rect x={tooltipX} y={priceTop + 6} width={154} height={70}
                  fill={ST.panel} stroke={ST.borderHi} rx="4" />
                <text x={tooltipX + 8} y={priceTop + 20}
                  fontFamily="JetBrains Mono" fontSize="9" fill={ST.ink3}>O <tspan fill={ST.ink}>{fmtP(c.o)}</tspan></text>
                <text x={tooltipX + 80} y={priceTop + 20}
                  fontFamily="JetBrains Mono" fontSize="9" fill={ST.ink3}>H <tspan fill={ST.green}>{fmtP(c.h)}</tspan></text>
                <text x={tooltipX + 8} y={priceTop + 34}
                  fontFamily="JetBrains Mono" fontSize="9" fill={ST.ink3}>L <tspan fill={ST.red}>{fmtP(c.l)}</tspan></text>
                <text x={tooltipX + 80} y={priceTop + 34}
                  fontFamily="JetBrains Mono" fontSize="9" fill={ST.ink3}>C <tspan fill={c.c >= c.o ? ST.green : ST.red}>{fmtP(c.c)}</tspan></text>
                <text x={tooltipX + 8} y={priceTop + 50}
                  fontFamily="JetBrains Mono" fontSize="9" fill={ST.ink3}>V <tspan fill={ST.ink}>{c.v.toFixed(2)}B</tspan></text>
                <text x={tooltipX + 8} y={priceTop + 64}
                  fontFamily="JetBrains Mono" fontSize="9" fill={ST.ink4}>{candles.length - hover.idx}d ago</text>
              </g>
            );
          })()}
        </g>
      )}
    </svg>
  );
}

/* ── Helpers: EMA + VWAP + RSI (same as Coin page) ─────────────────── */
window.ST_ema = (candles, period) => {
  const k = 2 / (period + 1);
  let e = candles[0].c;
  return candles.map((c, i) => { e = c.c * k + e * (1 - k); return e; });
};
window.ST_vwap = (candles) => {
  let cumPV = 0, cumV = 0;
  return candles.map(c => {
    const typ = (c.h + c.l + c.c) / 3;
    cumPV += typ * c.v;
    cumV  += c.v;
    return cumPV / cumV;
  });
};
window.ST_rsi = (candles, period = 14) => {
  let gains = 0, losses = 0;
  const out = [];
  for (let i = 0; i < candles.length; i++) {
    if (i === 0) { out.push(50); continue; }
    const diff = candles[i].c - candles[i - 1].c;
    const g = Math.max(0, diff), l = Math.max(0, -diff);
    if (i <= period) {
      gains += g; losses += l;
      if (i === period) {
        const ag = gains / period, al = losses / period;
        out.push(100 - 100 / (1 + ag / (al || 0.0001)));
      } else {
        out.push(50);
      }
    } else {
      const ag = (gains * (period - 1) + g) / period;
      const al = (losses * (period - 1) + l) / period;
      gains = ag; losses = al;
      out.push(100 - 100 / (1 + ag / (al || 0.0001)));
    }
  }
  return out;
};

/* Memoize chart — re-render only on coin switch / overlay change, not every
   live tick. The inner STProChart fetches its own candles. The header strip
   needs live, so allow re-render when price moves. */
window.HeroChart = React.memo(HeroChart, (prev, next) => {
  return prev.orders  === next.orders  &&
         prev.supportZones === next.supportZones &&
         prev.resistanceZones === next.resistanceZones &&
         prev.coin?.sym === next.coin?.sym &&
         prev.live?.price === next.live?.price;
});
