// BTC balance checker — parallel fetch (mempool + blockstream race), banner-style result card,
// rotating share copy. No data stored client- or server-side.

const BTC_REGEX = /^(bc1[0-9a-z]{8,87}|[13][a-km-zA-HJ-NP-Z1-9]{25,62})$/;

const BALANCE_APIS = [
  'https://mempool.space/api/address',
  'https://blockstream.info/api/address',
];

// Five rotating share messages — picked at random each time the user clicks Share.
const SHARE_MESSAGES = [
  'Just checked: I\'m getting {btc} eCash on fork day 🌶️ Every BTC holder gets matched 1:1 at block 964,000. Yours: ecash.com',
  'Free eCash incoming: {btc} 🪙 Drivechain hardfork drops Aug 21. Check yours: ecash.com',
  '{btc} eCash to me, please. (Bitcoin\'s first 1:1 hardfork dividend, August 21.) ecash.com',
  'BTC pays a dividend now. {btc} eCash inbound for me on fork day. Yours: ecash.com',
  'Forked. I\'m getting {btc} eCash on Aug 21. Block 964,000. ecash.com',
];

function pickShareMessage(btc) {
  var m = SHARE_MESSAGES[Math.floor(Math.random() * SHARE_MESSAGES.length)];
  return m.replace('{btc}', btc.toFixed(5));
}

// Fire both APIs in parallel; whichever responds first wins.
// Each call has its own 5s abort. Promise.any rejects only if BOTH fail.
async function fetchBalance(address) {
  var attempts = BALANCE_APIS.map(function(base) {
    var ctrl = new AbortController();
    var timer = setTimeout(function() { ctrl.abort(); }, 5000);
    return fetch(base + '/' + address, { signal: ctrl.signal })
      .then(function(r) {
        clearTimeout(timer);
        if (!r.ok) throw new Error(base + ' ' + r.status);
        return r.json().then(function(d) {
          var sats = d.chain_stats.funded_txo_sum - d.chain_stats.spent_txo_sum;
          return { btc: sats / 1e8, source: new URL(base).hostname };
        });
      })
      .catch(function(e) { clearTimeout(timer); throw e; });
  });
  // Promise.any → first success. If all reject, throws AggregateError.
  try {
    return await Promise.any(attempts);
  } catch (err) {
    var msgs = (err.errors || [err]).map(function(e) { return e.message || String(e); }).join(' · ');
    throw new Error('upstreams unreachable: ' + msgs);
  }
}

function CountUp({ to, duration }) {
  duration = duration || 800;
  var [val, setVal] = React.useState(0);
  React.useEffect(function() {
    var raf, start;
    function tick(t) {
      if (!start) start = t;
      var p = Math.min(1, (t - start) / duration);
      var eased = 1 - Math.pow(1 - p, 3);
      setVal(to * eased);
      if (p < 1) raf = requestAnimationFrame(tick);
    }
    raf = requestAnimationFrame(tick);
    return function() { cancelAnimationFrame(raf); };
  }, [to, duration]);
  return React.createElement(React.Fragment, null, val.toFixed(5));
}

function BalanceChecker({ accent }) {
  accent = accent || '#e8a84a';
  var [addr, setAddr]         = React.useState('');
  var [status, setStatus]     = React.useState('empty'); // empty|loading|result|error
  var [result, setResult]     = React.useState(null);
  var [fetchErr, setFetchErr] = React.useState('');
  var [inputErr, setInputErr] = React.useState('');
  var [btnHover, setBtnHover]     = React.useState(false);
  var [shareHover, setShareHover] = React.useState(false);
  var [copied, setCopied]         = React.useState(false);

  async function handleCheck() {
    var a = addr.trim();
    if (!BTC_REGEX.test(a)) {
      setInputErr('Invalid BTC address — must start with bc1, 1, or 3.');
      return;
    }
    setInputErr('');
    setStatus('loading');
    var t0 = Date.now();
    try {
      var bal = await fetchBalance(a);
      // Force a minimum 350ms loading state so the count-up feels intentional.
      var delay = Math.max(0, 350 - (Date.now() - t0));
      setTimeout(function() {
        setResult({ address: a, btc: bal.btc, source: bal.source });
        setStatus('result');
        if (typeof window.plausible === 'function') window.plausible('balance_checked');
      }, delay);
    } catch (e) {
      setFetchErr('Could not fetch balance: ' + e.message);
      setStatus('error');
    }
  }

  function handleKey(e) { if (e.key === 'Enter') handleCheck(); }

  function handleShare() {
    if (!result) return;
    var text = pickShareMessage(result.btc);
    var url  = 'https://twitter.com/intent/tweet?text=' + encodeURIComponent(text);
    window.open(url, '_blank', 'noopener,noreferrer');
  }

  async function copyShareText() {
    if (!result) return;
    try {
      await navigator.clipboard.writeText(pickShareMessage(result.btc));
      setCopied(true);
      setTimeout(function() { setCopied(false); }, 1600);
    } catch (e) { /* noop */ }
  }

  var inputStyle = {
    flex: 1, minWidth: 0,
    background: '#0a0a0c',
    border: '1px solid ' + (inputErr ? '#dc2626' : '#27272a'),
    color: '#fafafa', padding: '12px 14px',
    fontFamily: 'inherit', fontSize: 13, letterSpacing: '0.03em',
    borderRadius: 3, outline: 'none',
    transition: 'border-color .15s',
  };

  var btnStyle = {
    background: btnHover ? accent + '14' : 'transparent',
    border: '1px solid ' + accent + (btnHover ? '' : '70'),
    color: accent,
    padding: '12px 22px',
    fontFamily: 'inherit', fontSize: 12, letterSpacing: '0.12em',
    textTransform: 'uppercase', cursor: 'pointer',
    borderRadius: 3, whiteSpace: 'nowrap',
    transition: 'background .15s, border-color .15s',
  };

  return (
    <section style={{ borderTop: '1px solid #1f1f23', background: '#0a0a0c' }}>
      <div style={{ maxWidth: 880, margin: '0 auto', padding: 'clamp(48px,7vh,72px) clamp(20px,5vw,32px)' }}>
        <div style={{ fontSize: 10, letterSpacing: '0.22em', color: '#52525b', textTransform: 'uppercase', marginBottom: 14 }}>§ check your eCash</div>
        <h2 style={{ fontSize: 'clamp(22px,4vw,32px)', fontWeight: 400, color: '#fafafa', letterSpacing: '-0.01em', lineHeight: 1.2, margin: '0 0 8px', fontFamily: 'inherit' }}>
          Your Balance
        </h2>
        <div style={{ fontSize: 13, color: '#71717a', marginBottom: 28, fontFamily: 'inherit' }}>
          Paste any BTC address. See what you'll receive on fork day.
        </div>

        {/* Input row */}
        <div style={{ display: 'flex', gap: 10, flexWrap: 'wrap', marginBottom: inputErr ? 8 : 0 }}>
          <input
            type="text"
            value={addr}
            onChange={function(e) { setAddr(e.target.value); setInputErr(''); }}
            onKeyDown={handleKey}
            placeholder="bc1q... or 1... or 3..."
            spellCheck={false}
            autoComplete="off"
            style={inputStyle}
            onFocus={function(e) { if (!inputErr) e.target.style.borderColor = accent; }}
            onBlur={function(e) { if (!inputErr) e.target.style.borderColor = '#27272a'; }}
          />
          <button
            onClick={handleCheck}
            onMouseEnter={function() { setBtnHover(true); }}
            onMouseLeave={function() { setBtnHover(false); }}
            disabled={status === 'loading'}
            style={btnStyle}
          >
            {status === 'loading' ? 'checking…' : 'check'}
          </button>
        </div>

        {inputErr && (
          <div style={{ color: '#ef4444', fontSize: 11, letterSpacing: '0.06em', marginTop: 6 }}>{inputErr}</div>
        )}

        {/* Sample address */}
        <button
          onClick={function() {
            setAddr('1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa');
            setInputErr('');
          }}
          style={{
            background: 'transparent', border: 'none', cursor: 'pointer', padding: 0,
            fontFamily: 'inherit', fontSize: 11, color: '#52525b', letterSpacing: '0.1em',
            textTransform: 'lowercase', textDecoration: 'underline dotted',
            textUnderlineOffset: 3, marginTop: 12,
          }}
        >
          try Satoshi's address →
        </button>

        {/* Empty state */}
        {status === 'empty' && (
          <div style={{
            marginTop: 28, padding: 'clamp(20px,4vh,28px)',
            border: '1px dashed #1f1f23', borderRadius: 4,
            color: '#3f3f46', fontSize: 12, letterSpacing: '0.06em',
            textAlign: 'center', lineHeight: 1.7,
          }}>
            Paste any BTC address above to see your future eCash balance.
            <br />
            <span style={{ color: '#27272a' }}>1:1 airdrop · snapshot at block ~{window.ECASH_CONSTANTS.TARGET_BLOCK.toLocaleString()}</span>
          </div>
        )}

        {/* Loading state */}
        {status === 'loading' && (
          <div style={{
            marginTop: 28, padding: 'clamp(20px,4vh,28px)',
            border: '1px dashed ' + accent + '40', borderRadius: 4,
            color: accent + 'b0', fontSize: 12, letterSpacing: '0.1em', textTransform: 'uppercase',
            textAlign: 'center',
          }}>
            querying chain<span className="dots-anim">…</span>
          </div>
        )}

        {/* Result — banner-style for screenshot-worthiness */}
        {status === 'result' && result && (
          <div style={{
            marginTop: 28,
            border: '1px solid ' + accent + '40',
            borderTop: '2px solid ' + accent,
            borderRadius: 4,
            padding: 'clamp(28px,5vh,44px)',
            background: 'linear-gradient(180deg, ' + accent + '06 0%, transparent 60%), #0d0d0f',
            boxShadow: '0 0 60px ' + accent + '08',
            position: 'relative',
            overflow: 'hidden',
          }}>
            {/* Soft accent glow blob, top-right */}
            <div style={{
              position: 'absolute', top: -40, right: -40, width: 220, height: 220,
              background: accent, opacity: 0.05, filter: 'blur(60px)', borderRadius: '50%',
              pointerEvents: 'none',
            }} />

            <div style={{ position: 'relative', zIndex: 1 }}>
              {/* Tiny prefix label */}
              <div style={{ fontSize: 10, letterSpacing: '0.22em', color: '#52525b', textTransform: 'uppercase', marginBottom: 16 }}>
                Future eCash balance · snapshot block {window.ECASH_CONSTANTS.TARGET_BLOCK.toLocaleString()}
              </div>

              {/* Hero number with count-up animation */}
              <div style={{
                fontSize: 'clamp(40px,9vw,76px)', fontWeight: 300,
                color: '#fafafa', letterSpacing: '-0.03em', lineHeight: 1,
                fontVariantNumeric: 'tabular-nums', marginBottom: 8,
                fontFamily: 'inherit',
              }}>
                <CountUp to={result.btc} duration={900} />
                <span style={{ color: accent, marginLeft: 14, fontSize: '0.38em', letterSpacing: '0.02em' }}>eCash</span>
              </div>

              <div style={{ fontSize: 13, color: '#71717a', letterSpacing: '0.04em', marginBottom: 20 }}>
                ≈ {result.btc.toFixed(8)} BTC at fork day · address{' '}
                <span style={{ color: '#a1a1aa' }}>
                  {result.address.slice(0, 8) + '…' + result.address.slice(-6)}
                </span>
              </div>

              {/* Tiny note */}
              <div style={{ fontSize: 11, color: '#52525b', letterSpacing: '0.04em', lineHeight: 1.6, marginBottom: 24, paddingRight: 'clamp(0px,12vw,80px)' }}>
                Snapshot taken at block {window.ECASH_CONSTANTS.TARGET_BLOCK.toLocaleString()} (≈ Aug 21, 2026). Move funds before then and your eCash balance follows.
              </div>

              {/* Share row */}
              <div style={{ display: 'flex', gap: 10, alignItems: 'center', flexWrap: 'wrap' }}>
                <button
                  onClick={handleShare}
                  onMouseEnter={function() { setShareHover(true); }}
                  onMouseLeave={function() { setShareHover(false); }}
                  style={{
                    background: shareHover ? accent + '20' : accent + '10',
                    border: '1px solid ' + accent,
                    color: accent,
                    padding: '10px 18px',
                    fontFamily: 'inherit', fontSize: 11, letterSpacing: '0.14em',
                    textTransform: 'uppercase', cursor: 'pointer',
                    borderRadius: 3,
                    transition: 'background .15s',
                  }}
                >
                  ✦ share on X
                </button>
                <button
                  onClick={copyShareText}
                  style={{
                    background: 'transparent',
                    border: '1px solid #27272a',
                    color: copied ? accent : '#71717a',
                    padding: '10px 14px',
                    fontFamily: 'inherit', fontSize: 11, letterSpacing: '0.12em',
                    textTransform: 'lowercase', cursor: 'pointer',
                    borderRadius: 3,
                    transition: 'color .15s, border-color .15s',
                  }}
                >
                  {copied ? '✓ copied' : 'copy text'}
                </button>
              </div>

              {/* Branding strip — appears in screenshots */}
              <div style={{
                position: 'absolute', bottom: -8, right: 0,
                fontSize: 10, letterSpacing: '0.32em', color: '#3f3f46', textTransform: 'uppercase',
              }}>
                ecash.com
              </div>
            </div>
          </div>
        )}

        {/* Error state */}
        {status === 'error' && (
          <div style={{
            marginTop: 28, padding: 'clamp(20px,4vh,28px)',
            border: '1px solid #dc262640', borderRadius: 4,
            color: '#fca5a5', fontSize: 12, letterSpacing: '0.04em', lineHeight: 1.7,
          }}>
            {fetchErr}
            <br />
            <button
              onClick={handleCheck}
              style={{
                background: 'transparent', border: 'none', cursor: 'pointer', padding: 0,
                fontFamily: 'inherit', fontSize: 11, color: accent, letterSpacing: '0.1em',
                textTransform: 'lowercase', textDecoration: 'underline dotted',
                textUnderlineOffset: 3, marginTop: 8,
              }}
            >
              retry →
            </button>
          </div>
        )}
      </div>

      {/* Loading dots animation */}
      <style>{
        '@keyframes dotsAnim { 0%,20%{ content: "."; } 40%{ content: ".."; } 60%,100%{ content: "..."; } }' +
        '.dots-anim::after { content: "..."; animation: dotsAnim 1.4s steps(3, end) infinite; }'
      }</style>
    </section>
  );
}

window.BalanceChecker = BalanceChecker;