#!/usr/bin/env python3
"""
BTC Momentum Prediction Bot v6 - Clean single-wallet rebuild
============================================================
Trades BTC 5-min UP/DOWN on Jupiter from ONE wallet (master).
- NO wallet rotation, NO SPL funding (the subsystem that stranded funds is gone)
- Momentum signal validated on Binance spot (3-min lookback, >$50, clean)
- Correct order format: always isYes=True, pick the Up/Down market by direction
- Trade -> hold to resolution -> claim winnings (friend's proven model)
- Crash-proof (every path wrapped), self-managing VPN routes
Fixes vs v5.9: master_pubkey NameError removed; double-wallet-creation removed;
rotation/funding removed; claim added so P&L reflects reality.
"""
import asyncio, json, time, os, csv, random, base64, threading, traceback, math
import urllib.request, urllib.parse, ssl, subprocess, socket
from datetime import datetime, timezone, timedelta
from collections import deque
from pathlib import Path
from http.server import HTTPServer, BaseHTTPRequestHandler

# --- CONFIG ---
def load_config():
    p = Path(__file__).parent / 'config.json'
    return json.load(open(p)) if p.exists() else {}

CFG = load_config()
JUP_API_KEY        = CFG.get('jup_api_key', '')
MASTER_SECRET_HEX  = CFG.get('master_wallet_secret_hex', '')
SOLANA_RPC         = CFG.get('solana_rpc', 'https://api.mainnet-beta.solana.com')
MOMENTUM_THRESHOLD = CFG.get('momentum_threshold', 50.0)
MAX_ENTRY_CENTS    = CFG.get('max_entry_cents', 60)
BET_SIZE_USDC      = CFG.get('bet_size_usdc', 5.0)
CLEANNESS_CHECK    = CFG.get('cleanness_check', True)
DELAY_RANGE        = CFG.get('delay_range', [2, 8])
DASHBOARD_PORT     = CFG.get('dashboard_port', 8080)
DATA_DIR           = Path(CFG.get('data_dir', 'data'))
USDC_MINT          = 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v'
DATA_DIR.mkdir(parents=True, exist_ok=True)

# --- GLOBAL STATE (no rotation state) ---
MASTER_PUBKEY = ''   # set at startup from the master keypair
HEALTH = {
    'bot_started': None, 'ws_connected': False, 'ws_last_connect': None,
    'ws_reconnects': 0, 'last_price': 0, 'last_price_time': 0,
    'prices_received': 0, 'current_momentum': 0, 'last_signal_time': None,
    'last_signal_action': None, 'usdc_balance': 0, 'sol_balance': 0,
    'errors': deque(maxlen=20), 'trade_attempts': [], 'windows_seen': 0,
    'routes_set': False, 'vpn_connected': False,
}

# --- LOGGING ---
def log(msg):
    ts = datetime.now(timezone.utc).strftime('%Y-%m-%d %H:%M:%S')
    print(f"[{ts}] {msg}", flush=True)

def log_error(msg, exc=None):
    ts = datetime.now(timezone.utc).strftime('%Y-%m-%d %H:%M:%S')
    err = f"[{ts}] ERROR: {msg}"
    if exc: err += f" | {type(exc).__name__}: {exc}"
    print(err, flush=True)
    HEALTH['errors'].append({'time': ts, 'msg': msg, 'exc': str(exc) if exc else ''})

# --- VPN + ROUTE SETUP (self-managed at startup + every 10 min) ---
def setup_routes():
    try:
        r = subprocess.run(['ip', 'addr', 'show', 'tun0'], capture_output=True, text=True)
        if r.returncode != 0:
            log("WARNING: tun0 not found. Attempting VPN reconnect...")
            HEALTH['vpn_connected'] = False
            try:
                subprocess.run(['sudo', 'openvpn', '--config', '/tmp/cz.ovpn', '--auth-user-pass',
                                '/tmp/vpn_auth.txt', '--route-nopull', '--daemon', '--log', '/tmp/vpn.log'],
                               capture_output=True)
                time.sleep(10)
                r2 = subprocess.run(['ip', 'addr', 'show', 'tun0'], capture_output=True, text=True)
                if r2.returncode != 0:
                    log("VPN reconnect failed - config files may be missing")
                    return False
                log("VPN reconnected")
            except Exception as e:
                log_error("VPN auto-reconnect", e); return False
        HEALTH['vpn_connected'] = True
        # CloudFront -> VPN (Jupiter API)
        try:
            data = json.loads(urllib.request.urlopen('https://ip-ranges.amazonaws.com/ip-ranges.json', timeout=10).read())
            cf = [p['ip_prefix'] for p in data['prefixes'] if p['service'] == 'CLOUDFRONT']
            for cidr in cf:
                subprocess.run(['sudo', 'ip', 'route', 'add', cidr, 'via', '10.8.8.1', 'dev', 'tun0'], capture_output=True)
            log(f"CloudFront: {len(cf)} ranges routed")
        except Exception as e:
            log_error("CloudFront route setup", e)
        # Binance -> VPN (dynamic IPs)
        try:
            ips = set(a[4][0] for a in socket.getaddrinfo('stream.binance.com', 9443))
            for ip in ips:
                subprocess.run(['sudo', 'ip', 'route', 'add', ip, 'via', '10.8.8.1', 'dev', 'tun0'], capture_output=True)
            log(f"Binance: {len(ips)} IPs routed")
        except Exception as e:
            log_error("Binance route setup", e)
        # Solana RPC direct (not through VPN)
        try:
            sol_ip = socket.getaddrinfo('api.mainnet-beta.solana.com', 443)[0][4][0]
            subprocess.run(['sudo', 'ip', 'route', 'add', sol_ip, 'via', '10.142.0.1'], capture_output=True)
        except: pass
        HEALTH['routes_set'] = True
        return True
    except Exception as e:
        log_error("setup_routes", e); return False

# --- SOLANA RPC ---
def sol_request(method, params):
    try:
        payload = json.dumps({'jsonrpc': '2.0', 'id': 1, 'method': method, 'params': params}).encode()
        req = urllib.request.Request(SOLANA_RPC, payload, {'Content-Type': 'application/json'})
        with urllib.request.urlopen(req, context=ssl.create_default_context(), timeout=15) as resp:
            return json.loads(resp.read())
    except Exception as e:
        log_error(f"Solana RPC {method}", e); return {'error': str(e)}

def get_sol_balance(pubkey):
    r = sol_request('getBalance', [pubkey]); return r.get('result', {}).get('value', 0)

def get_usdc_balance(pubkey):
    try:
        r = sol_request('getTokenAccountsByOwner', [pubkey, {'mint': USDC_MINT}, {'encoding': 'jsonParsed'}])
        for acc in r.get('result', {}).get('value', []):
            return float(acc['account']['data']['parsed']['info']['tokenAmount']['uiAmount'])
    except: pass
    return 0.0

def send_and_confirm_tx(signed_tx_b64):
    try:
        r = sol_request('sendTransaction', [signed_tx_b64, {'skipPreflight': True, 'encoding': 'base64', 'maxRetries': 5}])
        if 'error' in r: return None, r['error']
        sig = r.get('result')
        for _ in range(30):
            time.sleep(2)
            s = sol_request('getSignatureStatuses', [[sig]])
            val = s.get('result', {}).get('value', [None])[0]
            if val and val.get('confirmationStatus') in ('confirmed', 'finalized'): return sig, val.get('err')
            if val and val.get('err'): return sig, val['err']
        return sig, 'timeout'
    except Exception as e:
        return None, str(e)

# --- JUPITER API ---
def jup_request(method, path, data=None):
    try:
        url = f'https://api.jup.ag/prediction/v1{path}'
        if data:
            req = urllib.request.Request(url, json.dumps(data).encode(), method=method)
        else:
            req = urllib.request.Request(url, method=method)
        req.add_header('x-api-key', JUP_API_KEY)
        req.add_header('Content-Type', 'application/json')
        req.add_header('User-Agent', 'curl/8.5.0')
        with urllib.request.urlopen(req, context=ssl.create_default_context(), timeout=15) as resp:
            return json.loads(resp.read())
    except urllib.error.HTTPError as e:
        body = ''
        try: body = e.read().decode()[:300]
        except: pass
        return {'error': f'HTTP {e.code}: {body}'}
    except Exception as e:
        return {'error': str(e)}

def find_btc_5m_market():
    """Return both Up and Down markets for the live BTC 5-min window."""
    try:
        result = jup_request('GET', '/events?category=crypto&filter=live&includeMarkets=true')
        for event in result.get('data', []):
            title = event.get('metadata', {}).get('title', '').lower()
            if 'bitcoin up or down' in title and 'pm-' in title:
                up_m = down_m = None
                for market in event.get('markets', []):
                    if market.get('status') != 'open': continue
                    mt = market.get('title', '').lower()
                    p = market.get('pricing', {})
                    info = {'market_id': market['marketId'], 'buy_yes': p.get('buyYesPriceUsd', 0),
                            'close_time': market.get('closeTime')}
                    if mt == 'up': up_m = info
                    elif mt == 'down': down_m = info
                if up_m or down_m:
                    return {'event_id': event.get('eventId', ''), 'title': event['metadata']['title'],
                            'up': up_m, 'down': down_m}
        return None
    except Exception as e:
        log_error("find_btc_5m_market", e); return None

def create_order(wallet_pubkey, market_id, amount_usdc):
    """Always isYes=True - the correct Up/Down market is chosen before calling."""
    try:
        data = {'ownerPubkey': wallet_pubkey, 'marketId': market_id, 'isYes': True, 'isBuy': True,
                'depositAmount': str(int(amount_usdc * 1_000_000)), 'depositMint': USDC_MINT}
        return jup_request('POST', '/orders', data)
    except Exception as e:
        return {'error': str(e)}

def check_event_resolution(event_id):
    """Markets at TOP level; result is 'yes'/'no' on the Up market after settlement."""
    try:
        result = jup_request('GET', f'/events/{event_id}')
        if 'error' in result: return None
        for m in result.get('markets', []):
            if m.get('result') is not None and m.get('title', '').lower() == 'up':
                return 'UP' if m['result'] == 'yes' or m['result'] is True else 'DOWN'
        return None
    except: return None

# --- WALLET + SIGNING (single master wallet only) ---
def get_keypair(secret_hex):
    from solders.keypair import Keypair
    return Keypair.from_bytes(bytes.fromhex(secret_hex))

def sign_and_send(tx_b64, secret_hex):
    """Partial signing - Jupiter's co-signer already signed."""
    try:
        from solders.keypair import Keypair
        from solders.transaction import VersionedTransaction
        from solders.message import to_bytes_versioned
        kp = Keypair.from_bytes(bytes.fromhex(secret_hex))
        tx = VersionedTransaction.from_bytes(base64.b64decode(tx_b64))
        msg = to_bytes_versioned(tx.message)
        sigs = list(tx.signatures)
        me = kp.pubkey()
        for i in range(tx.message.header.num_required_signatures):
            if tx.message.account_keys[i] == me:
                sigs[i] = kp.sign_message(msg)
        signed = VersionedTransaction.populate(tx.message, sigs)
        return send_and_confirm_tx(base64.b64encode(bytes(signed)).decode())
    except Exception as e:
        log_error("sign_and_send", e); return None, str(e)

def claim_winnings():
    """Claim any claimable positions on the master wallet (realizes wins into USDC)."""
    claimed = 0
    try:
        r = jup_request('GET', f'/positions?ownerPubkey={MASTER_PUBKEY}')
        positions = r.get('data', r) if isinstance(r, dict) else r
        for p in (positions or []):
            if not isinstance(p, dict): continue
            if p.get('claimable') and not p.get('claimed'):
                pk = p.get('positionPubkey') or p.get('pubkey')
                if not pk: continue
                cr = jup_request('POST', f'/positions/{pk}/claim', {})
                b64 = cr.get('transaction') or cr.get('tx')
                if b64:
                    sig, err = sign_and_send(b64, MASTER_SECRET_HEX)
                    if not err:
                        claimed += 1
                        log(f"Claimed position {pk[:12]} (sig {str(sig)[:16]})")
    except Exception as e:
        log_error("claim_winnings", e)
    return claimed

# --- MOMENTUM ENGINE ---
class MomentumEngine:
    def __init__(self):
        self.prices = deque(maxlen=600)
        self.last_signal_window = None

    def add_price(self, price, ts):
        self.prices.append((ts, price))
        HEALTH['last_price'] = price
        HEALTH['last_price_time'] = ts
        HEALTH['prices_received'] += 1

    def get_momentum(self):
        if len(self.prices) < 30: return 0
        now_ts, now_price = self.prices[-1]
        target = now_ts - 180
        for ts, p in self.prices:
            if ts >= target - 3: return now_price - p
        return 0

    def check(self):
        if len(self.prices) < 30: return None
        now_ts, now_price = self.prices[-1]
        ws = (int(now_ts) // 300) * 300
        secs_in = now_ts - ws
        mom = self.get_momentum()
        HEALTH['current_momentum'] = mom
        if secs_in > 20 or self.last_signal_window == ws: return None
        if abs(mom) < MOMENTUM_THRESHOLD: return None
        if CLEANNESS_CHECK:
            samples = []
            for offset in [180, 120, 60, 0]:
                t = now_ts - offset
                for ts, p in self.prices:
                    if abs(ts - t) < 3: samples.append(p); break
            if len(samples) >= 4:
                steps = [samples[i+1]-samples[i] for i in range(len(samples)-1)]
                if not (all(s > 2 for s in steps) or all(s < -2 for s in steps)): return None
        self.last_signal_window = ws
        HEALTH['windows_seen'] += 1
        return {'window_start': ws, 'direction': 'UP' if mom > 0 else 'DOWN',
                'momentum': mom, 'price': now_price, 'timestamp': now_ts}

# --- CSV LOGGING ---
TRADES_FILE  = DATA_DIR / 'trades.csv'
SIGNALS_FILE = DATA_DIR / 'signals.csv'
WINDOWS_FILE = DATA_DIR / 'windows.csv'
BALANCE_FILE = DATA_DIR / 'balance_history.csv'
AUDIT_FILE   = DATA_DIR / 'audit.csv'

def init_csv(path, headers):
    if not path.exists():
        with open(path, 'w', newline='') as f: csv.writer(f).writerow(headers)

init_csv(TRADES_FILE, ['time','window','direction','momentum','entry_cents','amount','market_id','tx_sig','status','pnl','balance'])
init_csv(SIGNALS_FILE, ['time','window','direction','momentum','price','action'])
init_csv(AUDIT_FILE, ['time','check','status','detail'])
init_csv(BALANCE_FILE, ['time','usdc','sol','event'])
init_csv(WINDOWS_FILE, ['window_start','window_utc','momentum','direction','decision','reason','resolution','event_id','pnl'])

def log_signal(signal, action):
    HEALTH['last_signal_time'] = datetime.now(timezone.utc).isoformat()
    HEALTH['last_signal_action'] = action
    try:
        with open(SIGNALS_FILE, 'a', newline='') as f:
            csv.writer(f).writerow([datetime.now(timezone.utc).isoformat(), signal['window_start'],
                signal['direction'], f"{signal['momentum']:.1f}", f"{signal['price']:.2f}", action])
    except: pass

def log_trade(window, direction, momentum, entry, amount, market_id, tx_sig, status, pnl=0, balance=0):
    try:
        with open(TRADES_FILE, 'a', newline='') as f:
            csv.writer(f).writerow([datetime.now(timezone.utc).isoformat(), window, direction,
                f"{momentum:.1f}", entry, amount, market_id, tx_sig, status, f"{pnl:.2f}", f"{balance:.2f}"])
    except: pass

def log_window(window_start, momentum, direction, decision, reason, event_id=''):
    try:
        utc = datetime.fromtimestamp(window_start, tz=timezone.utc).strftime('%Y-%m-%d %H:%M')
        with open(WINDOWS_FILE, 'a', newline='') as f:
            csv.writer(f).writerow([window_start, utc, f"{momentum:.1f}", direction, decision, reason, 'pending', event_id, ''])
    except: pass

def update_window_resolution(window_start, resolution, pnl=''):
    try:
        rows = list(csv.DictReader(open(WINDOWS_FILE)))
        with open(WINDOWS_FILE, 'w', newline='') as f:
            w = csv.DictWriter(f, fieldnames=['window_start','window_utc','momentum','direction','decision','reason','resolution','event_id','pnl'])
            w.writeheader()
            for r in rows:
                if str(r.get('window_start','')) == str(window_start):
                    r['resolution'] = resolution
                    if pnl: r['pnl'] = str(pnl)
                w.writerow(r)
    except: pass

def est_pnl(won, entry_cents, stake):
    """Estimate realized P&L. entry_cents in cents (e.g. 55). Win pays $1/share."""
    price = max(entry_cents / 100.0, 0.01)
    contracts = stake / price
    fee = math.ceil(0.07 * contracts * price * (1 - price) * 100) / 100
    return round(contracts - stake - fee, 2) if won else round(-stake, 2)

# --- TRADE EXECUTION (single master wallet) ---
async def execute_trade(signal):
    try:
        direction = signal['direction']
        delay = random.uniform(*DELAY_RANGE)
        log(f"Signal: {direction} (${signal['momentum']:+.0f}). Waiting {delay:.1f}s...")
        log_signal(signal, 'DETECTED')
        await asyncio.sleep(delay)

        market = None
        for attempt in range(5):
            market = find_btc_5m_market()
            if market: break
            log(f"Market retry {attempt+1}/5..."); await asyncio.sleep(2)
        if not market:
            log("No market found. Skipping."); log_signal(signal, 'NO_MARKET'); return

        side = market.get('up') if direction == 'UP' else market.get('down')
        if not side:
            log_signal(signal, 'NO_SIDE'); return

        # Price observation: watch until entry <= MAX_ENTRY_CENTS (prices start ~100c, settle)
        entry_cents = 999
        for _sec in range(30):
            try:
                mkt_r = find_btc_5m_market()
                if mkt_r:
                    sr = mkt_r.get('up') if direction == 'UP' else mkt_r.get('down')
                    if sr and sr.get('buy_yes', 0) > 0:
                        entry_cents = sr['buy_yes'] / 10000
                        side = sr
                        if entry_cents <= MAX_ENTRY_CENTS:
                            log(f"Entry: {entry_cents:.0f}c at sec {_sec*2}"); break
                        if _sec % 5 == 0: log(f"Price {entry_cents:.0f}c at sec {_sec*2}...")
            except: pass
            await asyncio.sleep(random.uniform(1.5, 2.5))
        if entry_cents > MAX_ENTRY_CENTS:
            log(f"Entry {entry_cents:.0f}c > max {MAX_ENTRY_CENTS}c. Skip.")
            log_signal(signal, f'TOO_EXPENSIVE_{entry_cents:.0f}c'); return

        actual_bet = round(BET_SIZE_USDC + random.uniform(-0.20, 0.30), 2)
        log(f"Placing {direction} ${actual_bet:.2f} @ {entry_cents:.0f}c on {market['title'][:40]}...")
        log_signal(signal, 'TRADING')
        log_window(signal['window_start'], signal['momentum'], direction, 'TRADE', f'entry {entry_cents:.0f}c', market.get('event_id',''))

        # Order retry (genuine transient "no shares" only; single wallet, no rotation)
        order = None
        for _oa in range(15):
            order = create_order(MASTER_PUBKEY, side['market_id'], actual_bet)
            if 'error' not in order and 'transaction' in order: break
            HEALTH['trade_attempts'].append({'time': datetime.now(timezone.utc).isoformat(),
                'attempt': _oa+1, 'error': str(order.get('error',''))[:100]})
            HEALTH['trade_attempts'] = HEALTH['trade_attempts'][-50:]
            log(f"Order retry {_oa+1}/15: {str(order.get('error',''))[:80]}")
            await asyncio.sleep(random.uniform(1.5, 4.0))
        if not order or 'error' in order or 'transaction' not in order:
            log(f"Order failed: {order}"); log_signal(signal, 'ORDER_ERROR'); return

        sig, err = sign_and_send(order['transaction'], MASTER_SECRET_HEX)
        if err:
            log(f"Tx error: {err}")
            log_trade(signal['window_start'], direction, signal['momentum'], entry_cents, actual_bet,
                      side['market_id'], str(sig) if sig else '', 'error')
            log_signal(signal, 'TX_ERROR'); return

        log(f"TRADE CONFIRMED! Sig: {sig}")
        balance = get_usdc_balance(MASTER_PUBKEY)
        HEALTH['usdc_balance'] = balance
        log_trade(signal['window_start'], direction, signal['momentum'], entry_cents, actual_bet,
                  side['market_id'], sig, 'placed', 0, balance)
        log_signal(signal, 'TRADED')

        asyncio.create_task(resolve_and_claim(side['market_id'], direction, signal['window_start'],
                                              entry_cents, actual_bet, sig, market.get('event_id','')))
    except Exception as e:
        log_error("execute_trade", e)

async def resolve_and_claim(market_id, direction, ws, entry, stake, tx_sig, event_id):
    try:
        wait = (ws + 300 + 30) - time.time()
        if wait > 0: await asyncio.sleep(wait)
        for attempt in range(20):
            try:
                if event_id:
                    res = check_event_resolution(event_id)
                    if res:
                        won = (direction == res)
                        if won:
                            await asyncio.sleep(5)
                            claim_winnings()
                        balance = get_usdc_balance(MASTER_PUBKEY)
                        HEALTH['usdc_balance'] = balance
                        pnl = est_pnl(won, entry, stake)
                        status = 'won' if won else 'lost'
                        log(f"{'WIN' if won else 'LOSS'}: {direction} bet, oracle={res}, pnl={pnl:+.2f}, balance=${balance:.2f}")
                        # supersede the 'placed' row with a resolved row
                        log_trade(ws, direction, 0, entry, stake, market_id, tx_sig, status, pnl, balance)
                        update_window_resolution(ws, res, f"{pnl:+.2f}")
                        return
            except Exception as e:
                log_error("resolve check", e)
            await asyncio.sleep(15)
        log("Resolution timeout.")
    except Exception as e:
        log_error("resolve_and_claim", e)

# --- DASHBOARD ---
PAGINATION_JS = '<script>document.querySelectorAll("h2").forEach(function(h){var t=h.nextElementSibling;if(!t||t.tagName!="TABLE")return;var rows=Array.from(t.querySelectorAll("tr")).slice(1);if(rows.length<=10)return;var pg=0,pp=10;function sh(){rows.forEach(function(r,i){r.style.display=(i>=pg*pp&&i<(pg+1)*pp)?"":"none";});b.textContent="Page "+(pg+1)+"/"+Math.ceil(rows.length/pp);}var nav=document.createElement("div");nav.style.cssText="margin:4px 0;display:flex;gap:8px;align-items:center";var pb=document.createElement("button");pb.textContent="Prev";pb.onclick=function(){if(pg>0){pg--;sh();}};var nb=document.createElement("button");nb.textContent="Next";nb.onclick=function(){if((pg+1)*pp<rows.length){pg++;sh();}};var b=document.createElement("span");[pb,b,nb].forEach(function(e){e.style.cssText="background:%23161b22;border:1px solid %2321262d;color:%23c9d1d9;padding:4px 8px;border-radius:4px;cursor:pointer;font-size:0.8em";nav.appendChild(e);});t.parentNode.insertBefore(nav,t.nextSibling);sh();});</script>'

def cet(utc_str, with_date=False):
    try:
        s = utc_str.replace('T', ' ').replace('Z', '')[:19] if utc_str else ''
        if len(s) >= 16:
            dt = datetime.fromisoformat(s) + timedelta(hours=2)
            return dt.strftime('%m-%d %H:%M') if with_date else dt.strftime('%H:%M:%S')
    except: pass
    return utc_str[:19] if utc_str else ''

def get_all_data():
    trades = list(csv.DictReader(open(TRADES_FILE))) if TRADES_FILE.exists() else []
    signals = list(csv.DictReader(open(SIGNALS_FILE))) if SIGNALS_FILE.exists() else []
    windows = list(csv.DictReader(open(WINDOWS_FILE))) if WINDOWS_FILE.exists() else []
    # A trade is resolved once per window; keep the last row per window with a won/lost status
    resolved = {}
    for t in trades:
        if t.get('status') in ('won', 'lost'):
            resolved[t.get('window')] = t
    resolved = list(resolved.values())
    wins = sum(1 for t in resolved if t['status'] == 'won')
    pnl = sum(float(t.get('pnl', 0) or 0) for t in resolved)
    return {'trades': trades[-20:], 'signals': signals[-30:], 'windows': windows[-30:],
            'resolved': len(resolved), 'wins': wins, 'losses': len(resolved)-wins,
            'pnl': pnl, 'wr': wins/max(len(resolved), 1)*100}

def dashboard_html():
    d = get_all_data(); h = HEALTH; now = time.time()
    ws = (int(now) // 300) * 300; secs_left = max(0, int(ws + 300 - now))
    next_cet = (datetime.fromtimestamp(ws+300, tz=timezone.utc)+timedelta(hours=2)).strftime('%H:%M:%S')
    price_age = now - h['last_price_time'] if h['last_price_time'] > 0 else 999
    ws_ok = h['ws_connected'] and price_age < 30
    pc = '#4ade80' if d['pnl'] >= 0 else '#f87171'
    wc = '#4ade80' if d['wr'] >= 60 else '#fbbf24' if d['wr'] >= 50 else '#f87171'
    mom = h['current_momentum']; mc = '#4ade80' if abs(mom) >= 50 else '#94a3b8'

    sig_rows = ''
    for sg in reversed(d['signals']):
        ac = sg.get('action', '')
        acol = '#4ade80' if 'TRADED' in ac else '#f87171' if 'ERROR' in ac or 'NO_' in ac else '#fbbf24' if 'DETECTED' in ac else '#60a5fa'
        sig_rows += f"<tr><td>{cet(sg.get('time',''),True)}</td><td>{sg.get('direction','')}</td><td>${sg.get('momentum','')}</td><td>${sg.get('price','')}</td><td style='color:{acol}'>{ac}</td></tr>"

    trade_rows = ''
    for t in reversed(d['trades']):
        sc = '#4ade80' if t.get('status')=='won' else '#f87171' if t.get('status') in ('lost','error','tx_error') else '#60a5fa'
        trade_rows += f"<tr><td>{cet(t.get('time',''),True)}</td><td>{t.get('direction','')}</td><td>${t.get('momentum','')}</td><td>{t.get('entry_cents','')}c</td><td>{t.get('amount','')}</td><td style='color:{sc}'>{t.get('status','')}</td><td>${t.get('pnl','0')}</td></tr>"

    win_rows = ''
    for w in reversed(d['windows']):
        rc = '#4ade80' if w.get('resolution')=='UP' else '#f87171' if w.get('resolution')=='DOWN' else '#fbbf24'
        corr = '-'
        if w.get('resolution') not in ('pending', ''):
            corr = 'YES' if w.get('direction')==w.get('resolution') else 'NO'
        cc = '#4ade80' if corr=='YES' else '#f87171' if corr=='NO' else '#484f58'
        win_rows += f"<tr><td>{cet(w.get('window_utc',''),True)}</td><td>${w.get('momentum','')}</td><td>{w.get('direction','')}</td><td>{w.get('decision','')}</td><td>{w.get('reason','')}</td><td style='color:{rc}'>{w.get('resolution','pending')}</td><td style='color:{cc}'>{corr}</td><td>{w.get('pnl','')}</td></tr>"

    bal_rows = ''
    try:
        for b in reversed(list(csv.DictReader(open(BALANCE_FILE)))[-15:]):
            bal_rows += f"<tr><td>{cet(b.get('time',''))}</td><td>${b.get('usdc','')}</td><td>{b.get('sol','')}</td><td>{b.get('event','')}</td></tr>"
    except: pass
    audit_rows = ''
    try:
        for a in reversed(list(csv.DictReader(open(AUDIT_FILE)))[-15:]):
            sc = '#4ade80' if a.get('status')=='OK' else '#f87171' if a.get('status')=='FAIL' else '#fbbf24'
            audit_rows += f"<tr><td>{cet(a.get('time',''))}</td><td>{a.get('check','')}</td><td style='color:{sc}'>{a.get('status','')}</td><td style='font-size:0.75em'>{a.get('detail','')[:60]}</td></tr>"
    except: pass
    err_rows = ''.join(f"<tr><td>{e['time'][-8:]}</td><td>{e['msg']}</td><td style='color:#f87171'>{e['exc'][:50]}</td></tr>" for e in list(h['errors'])[-5:])

    return f"""<!DOCTYPE html><html><head><title>BTC Bot v6</title><meta http-equiv=refresh content=10>
<style>*{{box-sizing:border-box;margin:0;padding:0}}body{{background:#0c0f1a;color:#c9d1d9;font-family:monospace;padding:16px;font-size:13px}}
h1{{color:#f0f6fc;font-size:1.4em;margin-bottom:12px}}h2{{color:#8b949e;font-size:0.95em;margin:16px 0 8px;text-transform:uppercase;letter-spacing:1px}}
.grid{{display:grid;grid-template-columns:repeat(auto-fit,minmax(130px,1fr));gap:8px;margin:10px 0}}
.card{{background:#161b22;border:1px solid #21262d;border-radius:6px;padding:12px;text-align:center}}
.card .l{{color:#8b949e;font-size:0.75em;margin-bottom:4px}}.card .v{{font-size:1.5em;font-weight:700}}
.cd{{background:#161b22;border:1px solid #21262d;border-radius:6px;padding:12px;display:flex;justify-content:space-between;align-items:center;margin:10px 0}}
.hp{{display:flex;gap:12px;flex-wrap:wrap;margin:8px 0}}.hp .d{{width:8px;height:8px;border-radius:50%;display:inline-block;margin-right:4px}}.hp span{{font-size:0.8em}}
table{{width:100%;border-collapse:collapse;margin:4px 0;font-size:0.85em}}th{{color:#8b949e;text-align:left;padding:6px 8px;border-bottom:1px solid #21262d}}td{{padding:5px 8px;border-bottom:1px solid #161b22}}
@keyframes blink{{50%{{opacity:0}}}}</style></head><body>
<h1>BTC Momentum Bot v6 (single wallet)</h1>
<div class=hp>
<span><span class=d style='background:{"#4ade80" if ws_ok else "#f87171"}'></span>Bot {'LIVE' if ws_ok else '<span style="animation:blink 1s infinite">CRASHED</span>'}</span>
<span><span class=d style='background:{"#4ade80" if h["ws_connected"] else "#f87171"}'></span>WS {'OK' if h['ws_connected'] else 'DOWN'}</span>
<span><span class=d style='background:{"#4ade80" if h["vpn_connected"] else "#f87171"}'></span>VPN {'OK' if h['vpn_connected'] else 'DOWN'}</span>
<span><span class=d style='background:{"#4ade80" if h["routes_set"] else "#f87171"}'></span>Routes {'OK' if h['routes_set'] else 'DOWN'}</span>
<span><span class=d style='background:{"#4ade80" if price_age<30 else "#f87171"}'></span>Data {'LIVE' if price_age<30 else f'STALE {price_age:.0f}s'}</span>
<span>Prices: {h['prices_received']:,}</span></div>
<div class=cd><div><span style='color:#8b949e'>Next (CET)</span><br>{next_cet}</div>
<div style='font-size:2em;font-weight:700;color:#58a6ff'>{secs_left//60}:{secs_left%60:02d}</div>
<div style='text-align:right'><span style='color:#8b949e'>BTC</span><br><span style='font-size:1.4em;font-weight:700'>${h['last_price']:,.2f}</span></div>
<div style='text-align:right'><span style='color:#8b949e'>3m Mom</span><br><span style='font-size:1.3em;font-weight:700;color:{mc}'>${mom:+,.0f}</span></div></div>
<div class=grid>
<div class=card><div class=l>P&L (est)</div><div class=v style='color:{pc}'>${d['pnl']:+.2f}</div></div>
<div class=card><div class=l>Win Rate</div><div class=v style='color:{wc}'>{d['wr']:.0f}%</div></div>
<div class=card><div class=l>W/L</div><div class=v>{d['wins']}/{d['losses']}</div></div>
<div class=card><div class=l>Balance</div><div class=v>${h['usdc_balance']:.2f}</div></div>
<div class=card><div class=l>SOL</div><div class=v style='font-size:1em'>{h['sol_balance']:.4f}</div></div>
<div class=card><div class=l>Signals</div><div class=v>{len(d['signals'])}</div></div></div>
<h2>Trades</h2><table><tr><th>Time CET</th><th>Dir</th><th>Mom</th><th>Entry</th><th>Amt</th><th>Status</th><th>P&L</th></tr>
{trade_rows or '<tr><td colspan=7 style="color:#484f58">No trades yet</td></tr>'}</table>
<h2>Signals</h2><table><tr><th>Time CET</th><th>Dir</th><th>Momentum</th><th>Price</th><th>Action</th></tr>
{sig_rows or '<tr><td colspan=5 style="color:#484f58">Waiting...</td></tr>'}</table>
<h2>5-Minute Windows</h2><table><tr><th>Window</th><th>Mom</th><th>Dir</th><th>Decision</th><th>Reason</th><th>Resolution</th><th>Correct?</th><th>P&L</th></tr>
{win_rows or '<tr><td colspan=8 style="color:#484f58">No windows yet</td></tr>'}</table>
<h2>Balance History</h2><table><tr><th>Time CET</th><th>USDC</th><th>SOL</th><th>Event</th></tr>{bal_rows or '<tr><td colspan=4 style=color:#484f58>-</td></tr>'}</table>
<h2>System Audit</h2><table><tr><th>Time</th><th>Check</th><th>Status</th><th>Detail</th></tr>{audit_rows or '<tr><td colspan=4 style=color:#484f58>-</td></tr>'}</table>
<h2>Errors</h2><table><tr><th>Time</th><th>Source</th><th>Error</th></tr>{err_rows or '<tr><td colspan=3 style=color:#484f58>-</td></tr>'}</table>
<div style='margin-top:14px'><a href='/download/trades' style='color:#58a6ff;margin-right:12px'>trades.csv</a><a href='/download/signals' style='color:#58a6ff;margin-right:12px'>signals.csv</a><a href='/download/windows' style='color:#58a6ff'>windows.csv</a></div>
<p style='color:#30363d;margin-top:12px;font-size:0.7em'>v6 single-wallet · CET · {datetime.now(timezone.utc).strftime('%H:%M:%S UTC')}</p>
{PAGINATION_JS}</body></html>"""

class ReuseHTTPServer(HTTPServer):
    allow_reuse_address = True
    allow_reuse_port = True

class DashHandler(BaseHTTPRequestHandler):
    def handle(self):
        try: super().handle()
        except: pass
    def do_GET(self):
        try:
            if self.path.startswith('/download/'):
                name = self.path.split('/')[-1]
                fmap = {'signals': SIGNALS_FILE, 'trades': TRADES_FILE, 'windows': WINDOWS_FILE}
                f = fmap.get(name)
                if f and f.exists():
                    self.send_response(200); self.send_header('Content-Type', 'text/csv')
                    self.send_header('Content-Disposition', f'attachment; filename={name}.csv'); self.end_headers()
                    self.wfile.write(open(f, 'rb').read()); return
            self.send_response(200); self.send_header('Content-Type', 'text/html'); self.end_headers()
            self.wfile.write(dashboard_html().encode())
        except: pass
    def log_message(self, *a): pass

def start_dashboard():
    srv = ReuseHTTPServer(('0.0.0.0', DASHBOARD_PORT), DashHandler)
    threading.Thread(target=srv.serve_forever, daemon=True).start()
    log(f"Dashboard: http://0.0.0.0:{DASHBOARD_PORT}")

# --- BINANCE WEBSOCKET ---
async def price_feed(engine):
    import websockets
    uri = 'wss://stream.binance.com:9443/ws/btcusdt@trade'
    while True:
        try:
            for ip in set(a[4][0] for a in socket.getaddrinfo('stream.binance.com', 9443)):
                subprocess.run(['sudo','ip','route','add',ip,'via','10.8.8.1','dev','tun0'], capture_output=True)
            async with websockets.connect(uri) as ws:
                HEALTH['ws_connected'] = True
                HEALTH['ws_last_connect'] = datetime.now(timezone.utc).isoformat()
                log("Binance WebSocket connected (BTCUSDT)")
                async for msg in ws:
                    try:
                        dd = json.loads(msg)
                        engine.add_price(float(dd['p']), float(dd['T'])/1000)
                    except: pass
        except Exception as e:
            HEALTH['ws_connected'] = False; HEALTH['ws_reconnects'] += 1
            log_error("WebSocket", e); await asyncio.sleep(5)

# --- MAINTENANCE ---
async def maintenance_loop():
    while True:
        try:
            if MASTER_PUBKEY:
                usdc = get_usdc_balance(MASTER_PUBKEY); sol = get_sol_balance(MASTER_PUBKEY)/1e9
                if abs(usdc - HEALTH['usdc_balance']) > 0.01 or HEALTH['usdc_balance'] == 0:
                    try:
                        with open(BALANCE_FILE, 'a', newline='') as f:
                            csv.writer(f).writerow([datetime.now(timezone.utc).isoformat(), f"{usdc:.2f}", f"{sol:.4f}", 'check'])
                    except: pass
                HEALTH['usdc_balance'] = usdc; HEALTH['sol_balance'] = sol
            claim_winnings()      # sweep any claimable wins into USDC
            setup_routes()
        except Exception as e:
            log_error("maintenance", e)
        await asyncio.sleep(600)

# --- MAIN TRADING LOOP ---
async def main_loop(engine):
    log("Waiting for momentum signals...")
    last_window_logged = 0; last_resolved = 0
    while True:
        try:
            now = time.time(); window_start = (int(now)//300)*300; secs_in = now - window_start
            if 1 < secs_in < 5 and window_start != last_window_logged:
                last_window_logged = window_start
                mom = engine.get_momentum(); direction = 'UP' if mom > 0 else 'DOWN'
                eid = ''
                for _ in range(3):
                    try:
                        mkt = find_btc_5m_market()
                        if mkt and mkt.get('event_id',''): eid = mkt['event_id']; break
                    except: pass
                    await asyncio.sleep(2)
                if abs(mom) < MOMENTUM_THRESHOLD:
                    log_window(window_start, mom, direction, 'SKIP', f'mom ${abs(mom):.0f} < ${MOMENTUM_THRESHOLD:.0f}', eid)
                else:
                    log_window(window_start, mom, direction, 'SIGNAL', f'mom ${abs(mom):.0f}', eid)
            prev_window = window_start - 300
            if prev_window > last_resolved and 5 < secs_in < 20:
                last_resolved = prev_window
                try:
                    for row in csv.DictReader(open(WINDOWS_FILE)):
                        if str(row.get('window_start','')) == str(prev_window):
                            eid = row.get('event_id','')
                            if eid:
                                res = check_event_resolution(eid)
                                if res: update_window_resolution(prev_window, res); log(f"Window {prev_window} -> {res}")
                            break
                except Exception as e:
                    log_error("resolution", e)
            signal = engine.check()
            if signal: await execute_trade(signal)
        except Exception as e:
            log_error("main_loop", e)
        await asyncio.sleep(0.5)

# --- SELF-AUDIT (trimmed) ---
async def self_audit_loop():
    await asyncio.sleep(300)
    while True:
        try:
            at = datetime.now(timezone.utc).isoformat()
            def la(check, status, detail):
                try:
                    with open(AUDIT_FILE, 'a', newline='') as f: csv.writer(f).writerow([at, check, status, detail[:200]])
                except: pass
            r = subprocess.run(['ip','addr','show','tun0'], capture_output=True, text=True)
            la('vpn', 'OK' if r.returncode==0 else 'FAIL', 'tun0 '+('exists' if r.returncode==0 else 'missing'))
            age = time.time()-HEALTH['last_price_time'] if HEALTH['last_price_time']>0 else 9999
            la('binance_ws', 'OK' if age<30 else 'FAIL', f'last price {age:.0f}s ago')
            try:
                mkt = find_btc_5m_market(); la('jupiter_api', 'OK' if mkt else 'WARN', f'market found: {bool(mkt)}')
            except Exception as e: la('jupiter_api', 'FAIL', str(e)[:150])
            la('balance', 'OK' if HEALTH['usdc_balance']>1 else 'WARN', f"${HEALTH['usdc_balance']:.2f} USDC")
            try:
                req = urllib.request.Request(f'http://localhost:{DASHBOARD_PORT}')
                resp = urllib.request.urlopen(req, timeout=5); la('dashboard', 'OK', f'status={resp.status}')
            except Exception as e: la('dashboard', 'FAIL', str(e)[:150])
            try:
                rr = subprocess.run(['df','-h','/'], capture_output=True, text=True)
                pct = rr.stdout.strip().split('\n')[1].split()[4].replace('%',''); la('disk', 'OK' if int(pct)<80 else 'WARN', f'{pct}% used')
            except: pass
        except Exception as e:
            log_error("self_audit", e)
        await asyncio.sleep(3600)

# --- MAIN ---
async def main():
    global MASTER_PUBKEY
    HEALTH['bot_started'] = time.time()
    log("BTC Momentum Bot v6 (single wallet) - LIVE")
    log("=" * 50)
    if MASTER_SECRET_HEX:
        try:
            MASTER_PUBKEY = str(get_keypair(MASTER_SECRET_HEX).pubkey())
            HEALTH['usdc_balance'] = get_usdc_balance(MASTER_PUBKEY)
            HEALTH['sol_balance'] = get_sol_balance(MASTER_PUBKEY)/1e9
            log(f"Wallet: {MASTER_PUBKEY}")
            log(f"Balance: {HEALTH['sol_balance']:.4f} SOL, ${HEALTH['usdc_balance']:.2f} USDC")
        except Exception as e:
            log_error("startup wallet", e)
    log("Setting up VPN routes..."); setup_routes()
    start_dashboard()
    engine = MomentumEngine()
    await asyncio.gather(price_feed(engine), main_loop(engine), maintenance_loop(), self_audit_loop())

if __name__ == '__main__':
    asyncio.run(main())
