/* Dulius App UI Kit — Score Gauge (the signature speedometer) */

const SCORE_BANDS = [
  ["#E05C5C", 300, 449],
  ["#F5A623", 450, 549],
  ["#F5D623", 550, 599],
  ["#7BC67E", 600, 699],
  ["#2DBD6E", 700, 749],
  ["#1B5C2E", 750, 850],
];
const SCORE_MIN = 300, SCORE_MAX = 850;

// Four official tiers (label shown under the score)
const SCORE_TIERS = [
  [300, 449, "Starting Out"],
  [450, 599, "Fair Standing"],
  [600, 749, "Good Standing"],
  [750, 850, "Elite"],
];

function bandFor(score) {
  let color = "#1B5C2E", name = "Elite";
  for (const [c, a, b] of SCORE_BANDS) if (score >= a && score <= b) { color = c; break; }
  for (const [a, b, n] of SCORE_TIERS) if (score >= a && score <= b) { name = n; break; }
  return { color, name };
}

function ScoreGauge({ value = 742, size = 260, animate = true, showLabel = true }) {
  const canAnimate = animate
    && (typeof document === "undefined" || document.visibilityState === "visible")
    && !(window.matchMedia && window.matchMedia("(prefers-reduced-motion: reduce)").matches);
  const [shown, setShown] = React.useState(canAnimate ? SCORE_MIN : value);
  React.useEffect(() => {
    if (!canAnimate) { setShown(value); return; }
    let raf, start, done = false;
    const dur = 1100;
    const from = SCORE_MIN;
    const finish = () => { if (!done) { done = true; setShown(value); } };
    const step = (t) => {
      if (!start) start = t;
      const p = Math.min(1, (t - start) / dur);
      const eased = 1 - Math.pow(1 - p, 3);
      setShown(Math.round(from + (value - from) * eased));
      if (p < 1) raf = requestAnimationFrame(step); else finish();
    };
    raf = requestAnimationFrame(step);
    // Safety net: guarantee the gauge lands on its true value even if rAF is
    // throttled (e.g. when the iframe/tab is backgrounded).
    const safety = setTimeout(finish, dur + 250);
    return () => { cancelAnimationFrame(raf); clearTimeout(safety); };
  }, [value, animate]);

  const W = size, H = size * 0.72;
  const cx = W / 2, cy = W / 2, r = W * 0.36;
  const START = -125, SWEEP = 250;
  const sw = Math.max(12, W * 0.062);
  const pol = (ang, rad) => {
    const a = (ang * Math.PI) / 180;
    return [cx + rad * Math.sin(a), cy - rad * Math.cos(a)];
  };
  const arc = (a0, a1, rad = r) => {
    const [x0, y0] = pol(a0, rad), [x1, y1] = pol(a1, rad);
    const large = a1 - a0 > 180 ? 1 : 0;
    return `M ${x0} ${y0} A ${rad} ${rad} 0 ${large} 1 ${x1} ${y1}`;
  };
  const f = (s) => (s - SCORE_MIN) / (SCORE_MAX - SCORE_MIN);
  const needleAng = START + f(shown) * SWEEP;
  const [nx, ny] = pol(needleAng, r - sw * 1.1);
  const band = bandFor(shown);

  const ticks = [];
  for (let s = SCORE_MIN; s <= SCORE_MAX; s += 50) {
    const a = START + f(s) * SWEEP;
    const [ix, iy] = pol(a, r - sw * 0.75);
    const [ox, oy] = pol(a, r + sw * 0.55);
    ticks.push(<line key={s} x1={ix} y1={iy} x2={ox} y2={oy} stroke="#C3CCC7" strokeWidth={s % 100 === 0 ? 2.5 : 1.5} />);
  }

  return (
    <div className="dgauge" style={{ width: W, height: H + (showLabel ? 0 : 0) }}>
      <svg width={W} height={H} viewBox={`0 0 ${W} ${cy + 8}`}>
        <path d={arc(START, START + SWEEP)} fill="none" stroke="#E8F0E8" strokeWidth={sw} strokeLinecap="round" />
        {SCORE_BANDS.map(([c, a, b], i) => (
          <path key={i} d={arc(START + f(a) * SWEEP, START + f(b) * SWEEP - (i < SCORE_BANDS.length - 1 ? 1.4 : 0))} fill="none" stroke={c} strokeWidth={sw} strokeLinecap="butt" />
        ))}
        {ticks}
        <line x1={cx} y1={cy} x2={nx} y2={ny} stroke="#1B5C2E" strokeWidth={Math.max(3.5, W * 0.018)} strokeLinecap="round" />
        <circle cx={cx} cy={cy} r={W * 0.034} fill="#fff" stroke="#1B5C2E" strokeWidth="3" />
      </svg>
      {showLabel && (
        <div className="dgauge-center" style={{ top: cy * 0.52 }}>
          <div className="dgauge-score dnum" style={{ color: band.color, fontSize: W * 0.19 }}>{shown}</div>
          <div className="dgauge-band" style={{ color: band.color }}>{band.name}</div>
        </div>
      )}
    </div>
  );
}

Object.assign(window, { ScoreGauge, SCORE_BANDS, SCORE_TIERS, SCORE_MIN, SCORE_MAX, bandFor });
