/* global React, store */
// Shared UI primitives

const { useState, useEffect, useRef } = React;

function Panel({ title, tag, actions, children, bodyFlush, className = "" }) {
  return (
    <div className={`panel ${className}`} style={{ display: "flex", flexDirection: "column", minHeight: 0, height: "100%" }}>
      <div className="panel-header">
        <span className="title">{title}</span>
        {tag ? <span className="panel-tag">{tag}</span> : null}
        <div style={{ flex: 1 }}/>
        {actions}
      </div>
      <div className="panel-body" style={{ padding: bodyFlush ? 0 : 10, flex: 1, minHeight: 0, overflow: "hidden" }}>
        {children}
      </div>
    </div>
  );
}

function StatCell({ label, value, sub, tone }) {
  return (
    <div style={{ padding: "8px 12px", borderRight: "1px solid var(--border)" }}>
      <div className="h-xxs">{label}</div>
      <div className={`tnum ${tone === "up" ? "up" : tone === "down" ? "down" : "bright"}`} style={{ fontSize: 18, marginTop: 2, letterSpacing: "-0.01em" }}>
        {value}
      </div>
      {sub ? <div style={{ fontSize: 10, marginTop: 1 }}>{sub}</div> : null}
    </div>
  );
}

// Volatility regime gauge — horizontal strip; 0 to 100 score
function RegimeGauge({ regime, score, vix, vixChange, nifty_atr_pct, news_severity_score, news_events_1h }) {
  const bands = [
    { name: "NORMAL",   short: "N", color: "var(--up)",       range: [0, 30] },
    { name: "WATCH",    short: "W", color: "var(--cyan)",     range: [30, 50] },
    { name: "ELEVATED", short: "E", color: "var(--amber)",    range: [50, 70] },
    { name: "HIGH",     short: "H", color: "var(--down)",     range: [70, 85] },
    { name: "EXTREME",  short: "X", color: "var(--critical)", range: [85, 101] },
  ];
  const active = bands.find(b => b.name === regime) || bands[0];

  const vixTone  = vix == null ? "faint" : vix >= 22 ? "down" : vix >= 16 ? "amber" : "up";
  const atrTone  = nifty_atr_pct == null ? "faint" : nifty_atr_pct >= 1.5 ? "down" : nifty_atr_pct >= 1.0 ? "amber" : "up";
  const newsTone = (news_severity_score || 0) >= 10 ? "down" : (news_severity_score || 0) >= 5 ? "amber" : "up";

  const sep = { borderRight: "1px solid var(--border)", paddingRight: 12, marginRight: 12 };
  const scoreNum = typeof score === "number" ? score : 0;

  return (
    <div style={{ display: "flex", alignItems: "center", padding: "8px 12px", fontSize: 11, minHeight: 40, flexWrap: "wrap", rowGap: 6 }}>
      <div style={{ ...sep, display: "flex", alignItems: "center", gap: 8 }}>
        <span className="h-xxs">VOL REGIME</span>
        <span style={{ fontSize: 11, fontWeight: 600, color: active.color, letterSpacing: "0.08em" }}>{regime}</span>
      </div>

      <div style={{ ...sep, display: "flex", gap: 2, height: 16, flex: 1, minWidth: 200, maxWidth: 360 }}>
        {bands.map(b => {
          const hi = b.name === "EXTREME" ? b.range[1] : b.range[1];
          const on = scoreNum >= b.range[0] && scoreNum < hi;
          return (
            <div key={b.name} title={`${b.name} (${b.range[0]}–${b.name === "EXTREME" ? 100 : b.range[1]})`}
              style={{
                flex: 1,
                background: on ? b.color : "var(--bg-0)",
                border: `1px solid ${on ? b.color : "var(--border)"}`,
                boxShadow: on ? `0 0 6px ${b.color}` : "none",
                display: "flex", alignItems: "center", justifyContent: "center",
                fontSize: 9, fontWeight: 700, letterSpacing: "0.05em",
                color: on ? "var(--bg-0)" : "var(--fg-faint)",
                transition: "all 0.3s",
              }}>
              {b.short}
            </div>
          );
        })}
      </div>

      <div style={sep}>
        <span className="tnum bright" style={{ fontSize: 14, fontWeight: 500 }}>{scoreNum.toFixed(0)}</span>
        <span className="faint" style={{ fontSize: 10 }}> / 100</span>
      </div>

      <div style={sep}>
        <span className="h-xxs" style={{ marginRight: 6 }}>VIX</span>
        <span className={`tnum ${vixTone}`} style={{ fontWeight: 500 }}>
          {vix != null ? vix.toFixed(2) : <span className="faint">—</span>}
        </span>
        {vixChange != null && vix != null ? (
          <span className="faint" style={{ marginLeft: 4, fontSize: 10 }}>
            ({vixChange >= 0 ? "+" : ""}{vixChange.toFixed(2)})
          </span>
        ) : null}
      </div>

      <div style={sep}>
        <span className="h-xxs" style={{ marginRight: 6 }}>ATR</span>
        <span className={`tnum ${atrTone}`} style={{ fontWeight: 500 }}>
          {nifty_atr_pct != null ? `${nifty_atr_pct.toFixed(2)}%` : <span className="faint">—</span>}
        </span>
        <span className="faint" style={{ marginLeft: 4, fontSize: 10 }}>14d</span>
      </div>

      <div>
        <span className="h-xxs" style={{ marginRight: 6 }}>NEWS 1h</span>
        <span className={`tnum ${newsTone}`} style={{ fontWeight: 500 }}>
          {news_severity_score != null ? news_severity_score : <span className="faint">—</span>}
        </span>
        {news_events_1h != null ? (
          <span className="faint" style={{ marginLeft: 4, fontSize: 10 }}>({news_events_1h} ev)</span>
        ) : null}
      </div>
    </div>
  );
}

function TickingPrice({ value }) {
  const prev = useRef(value);
  const [flash, setFlash] = useState(null);
  useEffect(() => {
    if (prev.current !== value) {
      setFlash(value > prev.current ? "up" : "down");
      const t = setTimeout(() => setFlash(null), 550);
      prev.current = value;
      return () => clearTimeout(t);
    }
  }, [value]);
  return (
    <span className={`ticking ${flash === "up" ? "flash-up" : flash === "down" ? "flash-down" : ""}`}>
      {typeof value === "number" ? value.toFixed(2) : value}
    </span>
  );
}

function Sparkline({ data, width = 80, height = 20, strokeWidth = 1 }) {
  if (!data || data.length < 2) return <svg width={width} height={height}/>;
  const min = Math.min(...data), max = Math.max(...data);
  const range = max - min || 1;
  const x = (i) => (i / (data.length - 1)) * width;
  const y = (v) => height - ((v - min) / range) * height;
  const path = "M " + data.map((v, i) => `${x(i)},${y(v)}`).join(" L ");
  const up = data[data.length - 1] >= data[0];
  const color = up ? "var(--up)" : "var(--down)";
  const areaPath = path + ` L ${width},${height} L 0,${height} Z`;
  return (
    <svg width={width} height={height} style={{ display: "block" }}>
      <path d={areaPath} fill={color} opacity="0.12"/>
      <path d={path} fill="none" stroke={color} strokeWidth={strokeWidth} />
    </svg>
  );
}

function WatchRow({ q, onClick }) {
  const chg = q.last - q.price;
  const chgPct = (chg / q.price) * 100;
  const up = chg >= 0;
  return (
    <div onClick={onClick} style={{
      display: "grid", gridTemplateColumns: "70px 1fr 64px 72px", alignItems: "center",
      padding: "4px 10px", borderBottom: "1px solid var(--grid)", cursor: "pointer",
    }} className="watchrow">
      <div>
        <div className="bright" style={{ fontSize: 11, fontWeight: 500 }}>{q.sym}</div>
        <div className="faint" style={{ fontSize: 8 }}>{q.exch}</div>
      </div>
      <div className="tnum" style={{ fontSize: 12 }}>
        <TickingPrice value={q.last}/>
      </div>
      <div style={{ textAlign: "center" }}>
        <Sparkline data={q.sparkline} width={60} height={14}/>
      </div>
      <div className={`tnum ${up ? "up" : "down"}`} style={{ fontSize: 11, textAlign: "right" }}>
        {up ? "+" : ""}{chgPct.toFixed(2)}%
      </div>
    </div>
  );
}

// Proposal card used on Dashboard
function ProposalCard({ p, expanded, onToggle, onConfirm, onReject }) {
  const isBuy = p.transaction_type === "BUY";
  const isClaude = p.source === "claude";
  return (
    <div style={{
      borderTop: "1px solid var(--border)",
      background: expanded ? "var(--bg-0)" : "transparent",
    }}>
      <div style={{
        padding: "10px 12px",
        display: "grid",
        gridTemplateColumns: "auto 100px 60px 1fr auto auto",
        gap: 12, alignItems: "center",
        borderLeft: `3px solid ${isBuy ? "var(--up)" : "var(--down)"}`,
      }}>
        <span className={isClaude ? "violet" : "cyan"} style={{ fontSize: 10, fontWeight: 500, letterSpacing: "0.08em", width: 60 }}>
          {isClaude ? "◆ CLAUDE" : "▸ " + p.source.replace("bot:", "").toUpperCase()}
        </span>
        <div>
          <span className="pill" style={{ color: isBuy ? "var(--up)" : "var(--down)", borderColor: isBuy ? "var(--up)" : "var(--down)", background: isBuy ? "rgba(34,214,111,0.08)" : "rgba(255,77,77,0.08)", fontWeight: 500 }}>
            {p.transaction_type}
          </span>
          <span className="bright" style={{ fontSize: 15, fontWeight: 500, marginLeft: 6, letterSpacing: "-0.01em" }}>{p.symbol}</span>
        </div>
        <span className="tnum" style={{ fontSize: 13 }}>×{p.quantity}</span>
        <span style={{ fontSize: 11, color: "var(--fg-dim)", lineHeight: 1.4 }} className="truncate-2">
          {p.rationale}
        </span>
        <div style={{ textAlign: "right" }}>
          <div className="tnum bright" style={{ fontSize: 12 }}>₹{p.reference_price.toFixed(2)}</div>
          <div className="faint tnum" style={{ fontSize: 9 }}>{store.inr(p.order_value)} · {p.order_type}</div>
        </div>
        <div style={{ display: "flex", gap: 4 }}>
          <button className="btn btn-xs btn-ghost" onClick={onToggle}>{expanded ? "×" : "⌄"}</button>
          <button className="btn btn-down" onClick={(e) => { e.stopPropagation(); onReject(p.request_id); }}>REJECT</button>
          <button className="btn btn-up" onClick={(e) => { e.stopPropagation(); onConfirm(p.request_id); }}>▸ CONFIRM</button>
        </div>
      </div>

      {expanded ? (
        <div style={{ padding: "0 12px 12px 30px", display: "grid", gridTemplateColumns: "1fr 1fr", gap: 16 }}>
          <div>
            <div className="h-xxs" style={{ marginBottom: 4 }}>RATIONALE</div>
            <div style={{ fontSize: 11, lineHeight: 1.6 }}>{p.rationale}</div>
            {p.bias ? (
              <div style={{ marginTop: 10, display: "grid", gridTemplateColumns: "repeat(3, 1fr)", gap: 4 }}>
                {[
                  ["VERDICT", p.bias.verdict, p.bias.verdict === "BULLISH" ? "up" : p.bias.verdict === "BEARISH" ? "down" : null],
                  ["SCORE", (p.bias.score > 0 ? "+" : "") + p.bias.score.toFixed(2), p.bias.score > 0 ? "up" : p.bias.score < 0 ? "down" : null],
                  ["RSI14", p.bias.rsi14?.toFixed(1)],
                  ["EMA20", p.bias.ema20?.toFixed(2)],
                  ["MACDh", p.bias.macd_hist?.toFixed(2)],
                  ["ATR14", p.bias.atr14?.toFixed(1)],
                ].map(([k, v, tone]) => (
                  <div key={k} style={{ padding: 4, background: "var(--bg-1)", border: "1px solid var(--border)" }}>
                    <div className="h-xxs" style={{ fontSize: 8 }}>{k}</div>
                    <div className={`tnum ${tone === "up" ? "up" : tone === "down" ? "down" : "bright"}`} style={{ fontSize: 11 }}>{v}</div>
                  </div>
                ))}
              </div>
            ) : null}
          </div>
          <div>
            <div className="h-xxs" style={{ marginBottom: 4 }}>PRE-TRADE RISK CHECKS</div>
            <div style={{ background: "var(--bg-1)", border: "1px solid var(--border)" }}>
              {p.risk_checks.map((c, i) => (
                <div key={i} style={{ display: "flex", alignItems: "center", gap: 6, padding: "4px 8px", borderBottom: i < p.risk_checks.length - 1 ? "1px solid var(--grid)" : "none", fontSize: 10 }}>
                  <span style={{ color: c.status === "pass" ? "var(--up)" : "var(--down)", width: 10 }}>{c.status === "pass" ? "✓" : "✗"}</span>
                  <span className="dim" style={{ width: 140, fontSize: 10 }}>{c.name}</span>
                  <span style={{ fontSize: 10 }}>{c.detail}</span>
                </div>
              ))}
            </div>
          </div>
        </div>
      ) : null}
    </div>
  );
}

Object.assign(window, { Panel, StatCell, RegimeGauge, TickingPrice, Sparkline, WatchRow, ProposalCard });
