// Verdict — live HL outcome detail modal: big chart, full L2 orderbook,
// wallet-connect, and a trade panel that builds the HL order action.

(function () {
  const { useState, useEffect, useMemo } = React;
  const Chart = () => (window.VDLiveChart && window.VDLiveChart.LiveBTCChart);
  const FlashNum  = window.VDFlash.FlashNum;
  const TickArrow = window.VDFlash.TickArrow;

  function fmtCents(p) { return p == null ? '—' : (p * 100).toFixed(1) + '¢'; }

  // Convert HL's pipe-separated description into a clean human-readable line.
  // "class:priceBinary|underlying:BTC|expiry:20260504-0600|targetPrice:78213|period:1d"
  // → ["Binary", "BTC", "Target $78,213", "Settles 2026-05-04 · 06:00 UTC", "Resets daily"]
  function formatOutcomeChips(parsed) {
    if (!parsed) return [];
    const out = [];
    const cls = (parsed.class || '').toLowerCase();
    if (cls === 'pricebinary')   out.push('Binary');
    else if (cls)                out.push(cls);
    if (parsed.underlying)       out.push(parsed.underlying);
    if (parsed.targetPriceNum != null) out.push('Target $' + parsed.targetPriceNum.toLocaleString());
    if (parsed.expiryMs) {
      const d = new Date(parsed.expiryMs);
      const date = d.toISOString().slice(0, 10);
      const time = d.toISOString().slice(11, 16);
      out.push(`Settles ${date} · ${time} UTC`);
    }
    if (parsed.period) {
      const periodMap = { '1d': 'Resets daily', '1w': 'Resets weekly', '1h': 'Hourly', '4h': '4-hour', '12h': '12-hour' };
      out.push(periodMap[parsed.period] || ('Period ' + parsed.period));
    }
    return out;
  }
  function fmtSize(sz) {
    if (sz == null) return '—';
    if (sz >= 1000) return (sz / 1000).toFixed(2) + 'k';
    if (sz >= 100) return Math.round(sz).toString();
    return sz.toFixed(0);
  }
  function fmtUsd0(v) { return v == null ? '—' : '$' + Math.round(v).toLocaleString(); }
  function shortAddr(a) { return a ? a.slice(0, 6) + '…' + a.slice(-4) : ''; }

  // ───────────────────────── Orderbook ladder ─────────────────────────
  function Ladder({ side, color, fullBook, mid }) {
    const bids = (fullBook && fullBook.bids) || [];
    const asks = (fullBook && fullBook.asks) || [];
    const maxSz = Math.max(
      ...bids.map(l => l.sz),
      ...asks.map(l => l.sz),
      1,
    );
    const spread = bids[0] && asks[0] ? (asks[0].px - bids[0].px) : null;

    const Row = ({ level, kind }) => {
      const fill = (level.sz / maxSz) * 100;
      const tone = kind === 'bid' ? 'var(--mint)' : 'var(--coral)';
      const bg   = kind === 'bid' ? 'var(--mint-bg10)' : 'var(--coral-bg10)';
      return (
        <div style={{
          position: 'relative', display: 'grid', gridTemplateColumns: '1fr 1fr 1fr',
          padding: '4px 10px', fontSize: 11, gap: 8, alignItems: 'center',
        }}>
          <div style={{
            position: 'absolute', right: 0, top: 0, bottom: 0, width: fill + '%',
            background: bg, borderLeft: `1px solid ${bg}`,
          }} />
          <div className="num" style={{ position: 'relative', color: tone, fontWeight: 600 }}>
            {fmtCents(level.px)}
          </div>
          <div className="num" style={{ position: 'relative', textAlign: 'right', color: 'var(--text-2)' }}>
            {fmtSize(level.sz)}
          </div>
          <div className="num" style={{ position: 'relative', textAlign: 'right', color: 'var(--text-3)' }}>
            {level.n}
          </div>
        </div>
      );
    };

    return (
      <div>
        <div className="cap" style={{
          display: 'grid', gridTemplateColumns: '1fr 1fr 1fr',
          padding: '8px 10px', borderBottom: '1px solid var(--line-subtle)', gap: 8,
        }}>
          <div>Price</div><div style={{textAlign:'right'}}>Size</div><div style={{textAlign:'right'}}>Orders</div>
        </div>

        {/* Asks descending so book looks like a single ladder with spread in the middle */}
        <div style={{ display: 'flex', flexDirection: 'column-reverse' }}>
          {asks.slice(0, 10).map((l, i) => <Row key={'a'+i} level={l} kind="ask" />)}
        </div>

        <div style={{
          display: 'flex', justifyContent: 'space-between',
          padding: '6px 10px',
          borderTop: '1px solid var(--line)',
          borderBottom: '1px solid var(--line)',
          background: 'var(--bg-elev-2)',
        }}>
          <span className="cap-sm" style={{ display: 'inline-flex', alignItems: 'center', gap: 4 }}>
            Mid <TickArrow value={mid} />
          </span>
          <span className="num" style={{ fontSize: 12, color, fontWeight: 600 }}>
            <FlashNum value={mid}>{fmtCents(mid)}</FlashNum>
          </span>
          <span className="cap-sm" style={{ color: 'var(--text-3)' }}>
            {spread != null ? Math.round(spread * 100) + '¢ spread' : '—'}
          </span>
        </div>

        <div>
          {bids.slice(0, 10).map((l, i) => <Row key={'b'+i} level={l} kind="bid" />)}
        </div>
      </div>
    );
  }

  // ───────────────────────── Trade panel ─────────────────────────
  function TradePanel({ outcome, btcMid, wallet, onConnect }) {
    const [side, setSide]   = useState('YES'); // YES | NO
    const [orderType, setOrderType] = useState('limit'); // limit | market
    const [sizeStr, setSizeStr]   = useState('100');
    const sideMid = side === 'YES' ? outcome.mid : (outcome.mid != null ? 1 - outcome.mid : null);
    const top = side === 'YES' ? outcome.books.yes : outcome.books.no;
    const defaultPx = (top && top.ask != null ? top.ask : (sideMid || 0.5)).toFixed(3);
    const [pxStr, setPxStr] = useState(defaultPx);

    useEffect(() => {
      // Auto-update default price when side flips or top-of-book moves materially
      const nextDefault = (top && top.ask != null ? top.ask : (sideMid || 0.5)).toFixed(3);
      setPxStr(nextDefault);
    }, [side, outcome.outcome]);

    const sz   = +sizeStr || 0;
    const px   = orderType === 'market'
      ? (top && top.ask != null ? top.ask : (sideMid || 0.5))
      : (+pxStr || 0);
    const cost = sz * px;
    const maxPayout = sz; // 1 contract pays $1 if right
    const ratio = px > 0 ? (1 - px) / px : 0;

    const assetId = side === 'YES' ? outcome.yesAssetId : outcome.noAssetId;

    const [submitState, setSubmitState] = useState({ phase: 'idle', msg: null, detail: null });
    // phase: idle | signing | broadcasting | success | error

    async function onSubmit() {
      if (!wallet.address) { setSubmitState({ phase: 'error', msg: 'Connect a wallet first.' }); return; }
      if (!sz || !px)      { setSubmitState({ phase: 'error', msg: 'Enter size and price.' }); return; }
      try {
        setSubmitState({ phase: 'signing', msg: 'Sign in your wallet…' });
        const params = {
          assetId,
          isBuy: true,
          priceStr: px.toString(),
          sizeStr: sz.toString(),
          tif: orderType === 'market' ? 'Ioc' : 'Gtc',
        };
        // Brief UI flicker so "Sign" state is visible even if MM popup is fast
        await new Promise(r => setTimeout(r, 50));
        const resp = await window.VDLive.submitOrder(params);
        // HL response: {status: 'ok'|'err', response: ...}
        if (resp.status !== 'ok') {
          setSubmitState({ phase: 'error', msg: typeof resp.response === 'string' ? resp.response : 'Order rejected.', detail: resp });
          return;
        }
        // Drill into the per-order status
        const data = resp.response && resp.response.data;
        const statuses = data && data.statuses;
        const first = Array.isArray(statuses) ? statuses[0] : null;
        if (first && first.error) {
          setSubmitState({ phase: 'error', msg: first.error, detail: resp });
          return;
        }
        let summary = 'Order accepted.';
        if (first && first.resting)  summary = `Resting · oid ${first.resting.oid}`;
        if (first && first.filled)   summary = `Filled ${first.filled.totalSz} @ ${first.filled.avgPx} · oid ${first.filled.oid}`;
        setSubmitState({ phase: 'success', msg: summary, detail: resp });
      } catch (e) {
        const m = (e && (e.shortMessage || e.message)) || String(e);
        // EIP-1193 user-rejected error code is 4001
        if (e && (e.code === 4001 || /reject/i.test(m))) {
          setSubmitState({ phase: 'idle', msg: null });
          return;
        }
        setSubmitState({ phase: 'error', msg: m });
      }
    }

    const sideColor = side === 'YES' ? 'var(--mint)' : 'var(--coral)';

    return (
      <div style={{ border: '1px solid var(--line)', background: 'var(--bg-elev)', padding: 16 }}>
        <div className="cap-sm" style={{ marginBottom: 10 }}>↳ Trade</div>

        {/* Side toggle */}
        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 0, marginBottom: 12 }}>
          {['YES', 'NO'].map(s => {
            const active = s === side;
            const c = s === 'YES' ? 'var(--mint)' : 'var(--coral)';
            return (
              <button key={s} onClick={() => setSide(s)} style={{
                padding: '10px 0',
                background: active ? (s === 'YES' ? 'var(--mint-bg10)' : 'var(--coral-bg10)') : 'transparent',
                color: active ? c : 'var(--text-2)',
                border: `1px solid ${active ? c : 'var(--line-subtle)'}`,
                fontWeight: 600, fontSize: 12, letterSpacing: '0.08em', textTransform: 'uppercase',
              }}>
                Buy {s === 'YES' ? outcome.yesLabel : outcome.noLabel}
              </button>
            );
          })}
        </div>

        {/* Order type */}
        <div style={{ display: 'flex', gap: 8, marginBottom: 12 }}>
          {['market', 'limit'].map(t => {
            const active = t === orderType;
            return (
              <button key={t} onClick={() => setOrderType(t)} className="cap-sm" style={{
                padding: '4px 10px',
                border: '1px solid ' + (active ? 'var(--acid)' : 'var(--line-subtle)'),
                color: active ? 'var(--acid)' : 'var(--text-3)',
                background: active ? 'var(--acid-bg10)' : 'transparent',
              }}>{t}</button>
            );
          })}
        </div>

        {/* Inputs */}
        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 10, marginBottom: 12 }}>
          <div>
            <div className="cap-sm" style={{ marginBottom: 4 }}>Size (contracts)</div>
            <input type="number" min="0" value={sizeStr} onChange={(e) => setSizeStr(e.target.value)}
                   className="num"
                   style={{
                     width: '100%', padding: '10px 12px', fontSize: 16,
                     background: 'var(--bg-elev-2)', border: '1px solid var(--line)',
                     outline: 'none', borderRadius: 'var(--r)', color: 'var(--text)',
                   }} />
          </div>
          <div>
            <div className="cap-sm" style={{ marginBottom: 4 }}>Limit (¢)</div>
            <input type="number" min="0" max="1" step="0.001"
                   value={pxStr} onChange={(e) => setPxStr(e.target.value)}
                   disabled={orderType === 'market'}
                   className="num"
                   style={{
                     width: '100%', padding: '10px 12px', fontSize: 16,
                     background: orderType === 'market' ? 'var(--bg-elev)' : 'var(--bg-elev-2)',
                     border: '1px solid var(--line)', outline: 'none', borderRadius: 'var(--r)',
                     color: orderType === 'market' ? 'var(--text-3)' : 'var(--text)',
                   }} />
          </div>
        </div>

        {/* Summary */}
        <div style={{ borderTop: '1px solid var(--line-subtle)', borderBottom: '1px solid var(--line-subtle)',
                       padding: '10px 0', display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 8, marginBottom: 12 }}>
          <div>
            <div className="cap-sm">Cost</div>
            <div className="num" style={{ fontSize: 14, fontWeight: 600 }}>{fmtUsd0(cost)}</div>
          </div>
          <div>
            <div className="cap-sm">Max payout</div>
            <div className="num" style={{ fontSize: 14, fontWeight: 600, color: sideColor }}>{fmtUsd0(maxPayout)}</div>
          </div>
          <div>
            <div className="cap-sm">Win/Risk</div>
            <div className="num" style={{ fontSize: 14, fontWeight: 600 }}>{ratio.toFixed(2)}×</div>
          </div>
        </div>

        {/* Wallet line */}
        {!wallet.address ? (
          <button onClick={onConnect} style={{
            width: '100%', padding: '12px 0', marginBottom: 10,
            border: '1px solid var(--acid)', color: 'var(--acid)', background: 'var(--acid-bg10)',
            fontWeight: 600, fontSize: 13, letterSpacing: '0.06em', textTransform: 'uppercase',
          }}>Connect Wallet</button>
        ) : (
          <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 10 }}>
            <span className="cap-sm">Wallet</span>
            <span className="num" style={{ fontSize: 12 }}>{shortAddr(wallet.address)}</span>
          </div>
        )}

        {/* Submit */}
        {(() => {
          const busy = submitState.phase === 'signing' || submitState.phase === 'broadcasting';
          const disabled = !sz || !px || busy;
          const label = busy
            ? (submitState.phase === 'signing' ? 'Signing…' : 'Broadcasting…')
            : `${orderType === 'market' ? 'Buy ' : 'Place limit '}${side === 'YES' ? outcome.yesLabel : outcome.noLabel} · ${(px * 100).toFixed(1)}¢`;
          return (
            <button onClick={onSubmit} disabled={disabled} style={{
              width: '100%', padding: '14px 0',
              background: busy ? 'var(--bg-elev-3)' : (side === 'YES' ? 'var(--mint)' : 'var(--coral)'),
              color: busy ? 'var(--text-2)' : 'var(--bg-base)',
              fontWeight: 700, fontSize: 13, letterSpacing: '0.08em', textTransform: 'uppercase',
              opacity: disabled && !busy ? 0.4 : 1, cursor: disabled ? 'not-allowed' : 'pointer',
            }}>
              {label}
            </button>
          );
        })()}

        {/* Deeplink fallback (kept tiny, only as a bail-out) */}
        <a href={window.VDLive.hlAppUrl(outcome.outcome, side === 'YES' ? 0 : 1)}
           target="_blank" rel="noopener"
           className="cap-sm"
           style={{ display: 'block', textAlign: 'center', marginTop: 10, color: 'var(--text-3)' }}>
          Or open in Hyperliquid app ↗
        </a>

        {/* Submit feedback */}
        {submitState.msg && submitState.phase !== 'idle' && (
          <div style={{
            marginTop: 12, padding: 10, fontSize: 11,
            border: '1px solid ' + (
              submitState.phase === 'success' ? 'var(--mint)' :
              submitState.phase === 'error'   ? 'var(--coral)' : 'var(--line)'
            ),
            color: submitState.phase === 'success' ? 'var(--mint)' :
                   submitState.phase === 'error'   ? 'var(--coral)' : 'var(--text-2)',
            background: 'var(--bg-elev-2)',
          }}>
            <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
              <span style={{ fontWeight: 700 }}>
                {submitState.phase === 'signing'      && '⟳'}
                {submitState.phase === 'broadcasting' && '⤴'}
                {submitState.phase === 'success'      && '✓'}
                {submitState.phase === 'error'        && '✗'}
              </span>
              <span>{submitState.msg}</span>
            </div>
          </div>
        )}
      </div>
    );
  }

  // ───────────────────────── Detail modal ─────────────────────────
  function DetailModal({ outcome, btcMid, wallet, onConnect, onClose }) {
    const [bookSide, setBookSide] = useState('YES');
    const target = outcome.parsed.targetPriceNum;
    const ChartC = Chart();

    // ESC to close
    useEffect(() => {
      const h = (e) => { if (e.key === 'Escape') onClose(); };
      window.addEventListener('keydown', h);
      return () => window.removeEventListener('keydown', h);
    }, [onClose]);

    const fullBook = bookSide === 'YES' ? outcome.fullBook.yes : outcome.fullBook.no;
    const sideMid = bookSide === 'YES' ? outcome.mid : (outcome.mid != null ? 1 - outcome.mid : null);

    return (
      <div onClick={onClose} style={{
        position: 'fixed', inset: 0, zIndex: 9999,
        background: 'rgba(0,0,0,0.78)',
        display: 'flex', alignItems: 'flex-start', justifyContent: 'center',
        padding: '40px 24px', overflowY: 'auto',
      }}>
        <div onClick={(e) => e.stopPropagation()} style={{
          width: '100%', maxWidth: 1200,
          background: 'var(--bg-base)', border: '1px solid var(--line)',
          borderRadius: 'var(--r)',
        }}>
          {/* Header */}
          <div style={{
            display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start',
            padding: '20px 24px', borderBottom: '1px solid var(--line-subtle)',
          }}>
            <div>
              <div className="cap-sm" style={{ marginBottom: 8, color: 'var(--acid)' }}>
                ↳ Hyperliquid HIP-4 · Outcome #{outcome.outcome} · {outcome.name}
              </div>
              <div className="serif" style={{ fontSize: 26, lineHeight: 1.1, letterSpacing: '-0.02em' }}>
                BTC &gt; ${(target || 0).toLocaleString()} at settle?
              </div>
              <div style={{ display: 'flex', flexWrap: 'wrap', gap: 6, marginTop: 10 }}>
                {formatOutcomeChips(outcome.parsed).map((chip, i) => (
                  <span key={i} className="cap-sm" style={{
                    padding: '3px 8px',
                    background: 'var(--bg-elev-2)',
                    border: '1px solid var(--line-subtle)',
                    color: 'var(--text-2)',
                    letterSpacing: '0.06em',
                  }}>{chip}</span>
                ))}
              </div>
            </div>
            <button onClick={onClose} className="cap-sm" style={{
              padding: '6px 10px', border: '1px solid var(--line)', color: 'var(--text-2)',
            }}>esc · close</button>
          </div>

          {/* Body */}
          <div style={{ display: 'grid', gridTemplateColumns: '1.55fr 1fr', gap: 0 }}>
            {/* Left: chart + trade */}
            <div style={{ padding: 24, borderRight: '1px solid var(--line-subtle)' }}>
              {ChartC ? <ChartC targetPrice={target} height={320} /> : null}

              <div style={{ marginTop: 24 }}>
                <TradePanel
                  outcome={outcome} btcMid={btcMid} wallet={wallet} onConnect={onConnect}
                />
              </div>
            </div>

            {/* Right: orderbook */}
            <div style={{ padding: 24 }}>
              <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 12 }}>
                <span className="cap-sm">↳ Order book</span>
                <div style={{ display: 'flex', gap: 0, border: '1px solid var(--line-subtle)' }}>
                  {['YES', 'NO'].map(s => {
                    const active = s === bookSide;
                    const c = s === 'YES' ? 'var(--mint)' : 'var(--coral)';
                    return (
                      <button key={s} onClick={() => setBookSide(s)} className="cap-sm" style={{
                        padding: '4px 12px',
                        background: active ? (s === 'YES' ? 'var(--mint-bg10)' : 'var(--coral-bg10)') : 'transparent',
                        color: active ? c : 'var(--text-3)',
                        borderRight: s === 'YES' ? '1px solid var(--line-subtle)' : 'none',
                      }}>{s === 'YES' ? outcome.yesLabel : outcome.noLabel}</button>
                    );
                  })}
                </div>
              </div>
              <div style={{ border: '1px solid var(--line-subtle)' }}>
                <Ladder side={bookSide}
                        color={bookSide === 'YES' ? 'var(--mint)' : 'var(--coral)'}
                        fullBook={fullBook}
                        mid={sideMid} />
              </div>

              {/* Underlying mini-summary */}
              <div style={{ marginTop: 16, padding: 12, border: '1px solid var(--line-subtle)' }}>
                <div className="cap-sm" style={{ marginBottom: 6, display: 'inline-flex', alignItems: 'center', gap: 4 }}>
                  ↳ Underlying <TickArrow value={btcMid} />
                </div>
                <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline' }}>
                  <span className="num" style={{ fontSize: 18, fontWeight: 500 }}>
                    <FlashNum value={btcMid}>{fmtUsd0(btcMid)}</FlashNum>
                  </span>
                  <span className="num" style={{
                    fontSize: 12,
                    color: btcMid != null && target != null
                      ? (btcMid >= target ? 'var(--mint)' : 'var(--coral)')
                      : 'var(--text-3)',
                  }}>
                    <FlashNum value={btcMid}>
                      {btcMid != null && target != null
                        ? (btcMid >= target ? '+' : '') + ((btcMid - target) / target * 100).toFixed(2) + '%'
                        : '—'}
                    </FlashNum>
                  </span>
                </div>
                <div className="cap-sm" style={{ marginTop: 4 }}>vs target {fmtUsd0(target)}</div>
              </div>
            </div>
          </div>
        </div>
      </div>
    );
  }

  window.VDLiveDetail = { DetailModal };
})();
