// CoolingThermometerV3.jsx — draggable GSAP thermometer, V3

function CoolingThermometerV3({ raised = 0, goal = 50000, onDonate, loading = false }) {
  var trackRef   = React.useRef(null);
  var handleRef  = React.useRef(null);
  var tooltipRef = React.useRef(null);
  var labelRef   = React.useRef(null);

  var STAGES = [
    { min: 0.000, label: 'Scorching'      },
    { min: 0.120, label: 'Critical'       },
    { min: 0.260, label: 'Dangerous'      },
    { min: 0.420, label: 'High Risk'      },
    { min: 0.570, label: 'Moderate'       },
    { min: 0.700, label: 'Getting Cooler' },
    { min: 0.840, label: 'Almost Safe'    },
    { min: 0.940, label: 'Safe Zone ✦'   },
    { min: 0.995, label: 'Cooled!'        },
  ];

  var [displayRaised, setDisplayRaised] = React.useState(0);
  var [displayPct, setDisplayPct]       = React.useState(0);
  var [stageLabel, setStageLabel]       = React.useState('Scorching');
  var [isDragging, setIsDragging]       = React.useState(false);

  var currentPRef  = React.useRef(0);
  var isDragRef    = React.useRef(false);
  var snapTweenRef = React.useRef(null);
  var proxyRef     = React.useRef({ p: 0 });

  function getLabel(p) {
    var lbl = STAGES[0].label;
    for (var i = 0; i < STAGES.length; i++) {
      if (p >= STAGES[i].min) lbl = STAGES[i].label;
    }
    return lbl;
  }

  function fmt(n) { return Math.round(n).toLocaleString('en-US'); }

  function applyPosition(p) {
    p = Math.max(0, Math.min(1, p));
    currentPRef.current = p;
    if (handleRef.current) {
      handleRef.current.style.left = (4 + p * 91) + '%';
      handleRef.current.setAttribute('aria-valuenow', Math.round(p * goal));
    }
    if (tooltipRef.current) {
      tooltipRef.current.textContent = '$' + fmt(p * goal);
    }
    var newLabel = getLabel(p);
    if (newLabel !== stageLabel && labelRef.current) {
      setStageLabel(newLabel);
    }
    setDisplayRaised(Math.round(p * goal));
    setDisplayPct(Math.round(p * 100));
  }

  function updateLabelAnimate(p) {
    var newLabel = getLabel(p);
    if (!labelRef.current) return;
    if (labelRef.current.textContent === newLabel) return;
    gsap.to(labelRef.current, {
      opacity: 0, y: -5, duration: 0.14,
      onComplete: function () {
        if (labelRef.current) labelRef.current.textContent = newLabel;
        gsap.fromTo(labelRef.current,
          { opacity: 0, y: 7 },
          { opacity: 1, y: 0, duration: 0.22, ease: 'power2.out' }
        );
      }
    });
  }

  function snapBack() {
    var targetP = raised / goal;
    if (snapTweenRef.current) snapTweenRef.current.kill();
    gsap.to(tooltipRef.current, { opacity: 0.55, duration: 0.12, ease: 'power2.in' });
    snapTweenRef.current = gsap.to(proxyRef.current, {
      p: targetP,
      duration: 0.85,
      ease: 'back.out(1.6)',
      onUpdate: function () {
        var p = proxyRef.current.p;
        currentPRef.current = p;
        if (handleRef.current) handleRef.current.style.left = (4 + p * 91) + '%';
        if (tooltipRef.current) tooltipRef.current.textContent = '$' + fmt(p * goal);
        updateLabelAnimate(p);
        setDisplayRaised(Math.round(p * goal));
        setDisplayPct(Math.round(p * 100));
      },
      onComplete: function () {
        if (tooltipRef.current) {
          tooltipRef.current.textContent = '$' + fmt(raised);
          gsap.to(tooltipRef.current, { opacity: 1, duration: 0.22, ease: 'power2.out' });
        }
        currentPRef.current = targetP;
        setDisplayRaised(raised);
        setDisplayPct(Math.round(targetP * 100));
      }
    });
  }

  var hasEnteredRef = React.useRef(false);

  // Entrance animation — waits for live data before firing (loading=false means API responded)
  React.useEffect(function () {
    if (loading) return;           // API still in flight — wait
    if (hasEnteredRef.current) return; // already ran
    hasEnteredRef.current = true;

    if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) {
      var p0 = raised / goal;
      applyPosition(p0);
      proxyRef.current.p = p0;
      return;
    }
    proxyRef.current.p = 0;
    applyPosition(0);
    var tween = gsap.to(proxyRef.current, {
      p: raised / goal,
      duration: 2.8,
      ease: 'power2.inOut',
      onUpdate: function () {
        var p = proxyRef.current.p;
        if (handleRef.current) handleRef.current.style.left = (4 + p * 91) + '%';
        if (tooltipRef.current) tooltipRef.current.textContent = '$' + fmt(p * goal);
        updateLabelAnimate(p);
        currentPRef.current = p;
        setDisplayRaised(Math.round(p * goal));
        setDisplayPct(Math.round(p * 100));
      },
      onComplete: function () {
        currentPRef.current = raised / goal;
        setDisplayRaised(raised);
        setDisplayPct(Math.round((raised / goal) * 100));
      }
    });
    return function () { tween.kill(); };
  }, [loading]); // fires once when loading flips false

  // Live data update — only after entrance has run
  React.useEffect(function () {
    if (!hasEnteredRef.current) return;
    if (isDragRef.current) return;
    var targetP = raised / goal;
    if (snapTweenRef.current) snapTweenRef.current.kill();
    gsap.to(proxyRef.current, {
      p: targetP,
      duration: 0.9,
      ease: 'power2.out',
      onUpdate: function () {
        var p = proxyRef.current.p;
        if (handleRef.current) handleRef.current.style.left = (4 + p * 91) + '%';
        if (tooltipRef.current) tooltipRef.current.textContent = '$' + fmt(p * goal);
        updateLabelAnimate(p);
        currentPRef.current = p;
        setDisplayRaised(Math.round(p * goal));
        setDisplayPct(Math.round(p * 100));
      },
      onComplete: function () {
        currentPRef.current = targetP;
        setDisplayRaised(raised);
        setDisplayPct(Math.round(targetP * 100));
        if (tooltipRef.current) tooltipRef.current.textContent = '$' + fmt(raised);
      }
    });
  }, [raised, goal]);

  function onPointerDown(e) {
    gsap.killTweensOf(proxyRef.current);
    if (snapTweenRef.current) snapTweenRef.current.kill();
    isDragRef.current = true;
    setIsDragging(true);
    handleRef.current.setPointerCapture(e.pointerId);
    gsap.to(tooltipRef.current, { opacity: 1, duration: 0.1 });
    e.preventDefault();
  }

  function onPointerMove(e) {
    if (!isDragRef.current) return;
    var rect = trackRef.current.getBoundingClientRect();
    var p = Math.max(0, Math.min(1, (e.clientX - rect.left) / rect.width));
    proxyRef.current.p = p;
    applyPosition(p);
    updateLabelAnimate(p);
  }

  function onPointerUp() {
    if (!isDragRef.current) return;
    isDragRef.current = false;
    setIsDragging(false);
    snapBack();
  }

  function onKeyDown(e) {
    var step = 1 / 100;
    var bigStep = 1 / 10;
    var p = currentPRef.current;
    var moved = false;
    if      (e.key === 'ArrowRight' || e.key === 'ArrowUp')  { p = Math.min(1, p + step);    moved = true; }
    else if (e.key === 'ArrowLeft'  || e.key === 'ArrowDown') { p = Math.max(0, p - step);    moved = true; }
    else if (e.key === 'PageUp')                              { p = Math.min(1, p + bigStep); moved = true; }
    else if (e.key === 'PageDown')                            { p = Math.max(0, p - bigStep); moved = true; }
    else if (e.key === 'Home')                                { p = 0; moved = true; }
    else if (e.key === 'End')                                 { p = 1; moved = true; }
    if (moved) {
      gsap.killTweensOf(proxyRef.current);
      if (snapTweenRef.current) snapTweenRef.current.kill();
      proxyRef.current.p = p;
      applyPosition(p);
      updateLabelAnimate(p);
      e.preventDefault();
    }
  }

  function onKeyUp(e) {
    var navKeys = ['ArrowRight','ArrowLeft','ArrowUp','ArrowDown','PageUp','PageDown','Home','End'];
    if (navKeys.indexOf(e.key) > -1) snapBack();
  }

  return (
    <div style={thermoV3.root}>
      <div style={thermoV3.housing}>
        <div ref={trackRef} style={thermoV3.track}>
          <div ref={labelRef} style={thermoV3.tempLabel}>{stageLabel}</div>
          <div
            ref={handleRef}
            style={{ ...thermoV3.handle, ...(isDragging ? thermoV3.handleDragging : {}) }}
            role="slider"
            tabIndex={0}
            aria-label="Donation amount"
            aria-valuemin={0}
            aria-valuemax={goal}
            aria-valuenow={Math.round((raised / goal) * goal)}
            onPointerDown={onPointerDown}
            onPointerMove={onPointerMove}
            onPointerUp={onPointerUp}
            onPointerCancel={onPointerUp}
            onKeyDown={onKeyDown}
            onKeyUp={onKeyUp}
          >
            <div ref={tooltipRef} style={{ ...thermoV3.tooltip, ...(isDragging ? thermoV3.tooltipDragging : {}) }}>
              ${fmt(raised)}
            </div>
            <div style={{ ...thermoV3.thumbBar, ...(isDragging ? thermoV3.thumbBarDragging : {}) }}>
              <div style={thermoV3.grip} />
            </div>
          </div>
        </div>
      </div>

      <div style={thermoV3.stats}>
        <div>
          <div style={thermoV3.metaLabel}>Raised so far</div>
          <div style={thermoV3.raisedAmount}>
            <span style={thermoV3.raisedSym}>$</span>
            <span>{fmt(displayRaised)}</span>
          </div>
        </div>
        <div style={{ textAlign: 'right' }}>
          <div style={thermoV3.metaLabel}>Goal</div>
          <div style={thermoV3.goalNum}>${fmt(goal)}</div>
        </div>
      </div>

      <div style={thermoV3.barWrap}>
        <span style={thermoV3.pctText}>{displayPct}% toward the cool zone</span>
        <div style={thermoV3.bar}>
          <div style={{ ...thermoV3.barFill, width: displayPct + '%' }} />
        </div>
      </div>

      <button
        onClick={function () { onDonate && onDonate(); }}
        style={thermoV3.cta}
        onMouseEnter={function (e) { e.currentTarget.style.background = 'linear-gradient(135deg, var(--lin_blue-600) 0%, var(--lin_navy-800) 100%)'; e.currentTarget.style.boxShadow = '0 6px 24px rgba(58,97,117,.45)'; }}
        onMouseLeave={function (e) { e.currentTarget.style.background = 'linear-gradient(135deg, var(--lin_blue-500) 0%, var(--lin_navy-700) 100%)'; e.currentTarget.style.boxShadow = '0 4px 18px rgba(99,153,175,.35)'; }}
      >
        ❄&nbsp; Cool it down | Give now
      </button>
    </div>
  );
}

var thermoV3 = {
  root: {
    fontFamily: 'var(--lin_font-family)',
    display: 'flex',
    flexDirection: 'column',
    alignItems: 'center',
    width: '100%',
  },
  housing: {
    position: 'relative',
    width: '100%',
    background: '#E5E5E9',
    borderRadius: 9999,
    padding: '16px 24px',
    marginBottom: '1.5rem',
    overflow: 'visible',
    boxShadow: [
      '14px 16px 40px rgba(0,0,0,0.18)',
      '-10px -10px 26px rgba(255,255,255,0.86)',
      'inset 0 2px 3px rgba(255,255,255,0.58)',
      'inset 0 -2px 3px rgba(0,0,0,0.06)',
    ].join(', '),
  },
  track: {
    position: 'relative',
    width: '100%',
    height: 62,
    borderRadius: 9999,
    overflow: 'visible',
    background: 'linear-gradient(to right, #C01A06 0%, #E8685A 18%, #F4956A 36%, #F2C96A 54%, #85B0C3 76%, #3A6175 100%)',
    boxShadow: [
      'inset 5px 6px 18px rgba(0,0,0,0.34)',
      'inset -3px -3px 8px rgba(255,255,255,0.06)',
      'inset 0 2px 6px rgba(0,0,0,0.2)',
    ].join(', '),
  },
  tempLabel: {
    position: 'absolute',
    inset: 0,
    display: 'flex',
    alignItems: 'center',
    justifyContent: 'center',
    fontSize: 'var(--lin_text-base)',
    fontWeight: 'var(--lin_weight-semibold)',
    color: 'rgba(255,255,255,0.93)',
    textShadow: '0 1px 8px rgba(0,0,0,.45), 0 0 24px rgba(0,0,0,.22)',
    letterSpacing: '0.025em',
    pointerEvents: 'none',
    userSelect: 'none',
    zIndex: 1,
  },
  handle: {
    position: 'absolute',
    top: 0,
    bottom: 0,
    left: '4%',
    transform: 'translateX(-50%)',
    display: 'flex',
    flexDirection: 'column',
    alignItems: 'center',
    justifyContent: 'center',
    zIndex: 4,
    cursor: 'grab',
    touchAction: 'none',
    userSelect: 'none',
    WebkitUserSelect: 'none',
    outline: 'none',
  },
  handleDragging: {
    cursor: 'grabbing',
  },
  tooltip: {
    position: 'absolute',
    bottom: 'calc(100% + 20px)',
    left: '50%',
    transform: 'translateX(-50%) scale(1)',
    transformOrigin: 'bottom center',
    minWidth: 112,
    textAlign: 'center',
    background: '#ffffff',
    borderRadius: 9999,
    padding: '7px 20px',
    whiteSpace: 'nowrap',
    fontSize: 'var(--lin_text-base)',
    fontWeight: 'var(--lin_weight-bold)',
    color: 'var(--lin_text-primary)',
    letterSpacing: '-0.01em',
    boxShadow: '0 6px 24px rgba(0,0,0,0.13), 0 2px 8px rgba(0,0,0,0.08), inset 0 1px 0 rgba(255,255,255,0.9)',
    pointerEvents: 'none',
  },
  tooltipDragging: {
    transform: 'translateX(-50%) scale(1.08)',
  },
  thumbBar: {
    position: 'relative',
    width: 22,
    height: 96,
    borderRadius: 9999,
    flexShrink: 0,
    background: 'linear-gradient(175deg, #ffffff 0%, #f4f4f6 35%, #d4d4d8 100%)',
    boxShadow: [
      '5px 10px 28px rgba(0,0,0,0.28)',
      '3px 4px 10px rgba(0,0,0,0.14)',
      'inset 0 3px 8px rgba(255,255,255,0.96)',
      'inset 0 -3px 6px rgba(0,0,0,0.10)',
    ].join(', '),
    transition: 'box-shadow 300ms ease',
  },
  grip: {
    position: 'absolute',
    left: '50%',
    top: '50%',
    transform: 'translate(-50%, -50%)',
    width: 9,
    height: 1.5,
    borderRadius: 1,
    background: 'rgba(0,0,0,.18)',
    boxShadow: '0 -5px 0 rgba(0,0,0,.18), 0 5px 0 rgba(0,0,0,.18)',
    pointerEvents: 'none',
  },
  thumbBarDragging: {
    boxShadow: [
      '8px 14px 36px rgba(0,0,0,0.34)',
      '4px 6px 14px rgba(0,0,0,0.18)',
      'inset 0 3px 8px rgba(255,255,255,0.96)',
      'inset 0 -3px 6px rgba(0,0,0,0.10)',
    ].join(', '),
  },
  stats: {
    display: 'flex',
    justifyContent: 'space-between',
    alignItems: 'flex-end',
    width: '100%',
    padding: '0 6px',
    marginBottom: '0.75rem',
  },
  metaLabel: {
    fontSize: 'var(--lin_text-xs)',
    fontWeight: 'var(--lin_weight-semibold)',
    letterSpacing: 'var(--lin_tracking-widest)',
    textTransform: 'uppercase',
    color: 'var(--lin_text-muted)',
    marginBottom: '0.3rem',
  },
  raisedAmount: {
    fontFamily: '"acumin-pro-wide", var(--lin_font-family)',
    fontSize: 'var(--lin_text-5xl)',
    fontWeight: '700',
    color: 'var(--lin_text-primary)',
    letterSpacing: 'var(--lin_tracking-tight)',
    lineHeight: 1,
  },
  raisedSym: {
    fontFamily: '"acumin-pro-wide", var(--lin_font-family)',
    fontSize: '0.42em',
    fontWeight: '500',
    color: 'var(--lin_text-muted)',
    verticalAlign: 'super',
    lineHeight: 0,
    marginRight: 1,
  },
  goalNum: {
    fontSize: 'var(--lin_text-lg)',
    fontWeight: 'var(--lin_weight-bold)',
    color: 'var(--lin_blue-700)',
    letterSpacing: '-0.01em',
  },
  barWrap: {
    width: '100%',
    padding: '0 6px',
    marginBottom: '1.25rem',
  },
  pctText: {
    display: 'block',
    fontSize: 'var(--lin_text-xs)',
    fontWeight: 'var(--lin_weight-semibold)',
    letterSpacing: 'var(--lin_tracking-widest)',
    textTransform: 'uppercase',
    color: 'var(--lin_blue-500)',
    marginBottom: '0.4rem',
  },
  bar: {
    width: '100%',
    height: 3,
    background: 'rgba(0,0,0,.09)',
    borderRadius: 9999,
    overflow: 'hidden',
  },
  barFill: {
    height: '100%',
    borderRadius: 9999,
    background: 'linear-gradient(to right, #E8685A 0%, var(--lin_blue-500) 100%)',
    transition: 'width 0.3s ease',
  },
  cta: {
    fontFamily: 'var(--lin_font-family)',
    fontSize: 'var(--lin_text-base)',
    fontWeight: 'var(--lin_weight-semibold)',
    letterSpacing: 'var(--lin_tracking-wide)',
    textTransform: 'none',
    border: 'none',
    cursor: 'pointer',
    borderRadius: 'var(--lin_radius-md)',
    padding: 'var(--lin_space-4) var(--lin_space-8)',
    background: 'linear-gradient(135deg, var(--lin_blue-500) 0%, var(--lin_navy-700) 100%)',
    color: '#fff',
    boxShadow: '0 4px 18px rgba(99,153,175,.35)',
    width: '100%',
    transition: 'box-shadow 200ms ease, background 200ms ease',
  },
};

Object.assign(window, { CoolingThermometerV3 });
