#!/usr/bin/env python3
"""
Crypto Price Fetcher
Pulls historical OHLCV data from Binance public API (no key needed).
"""

import json
import time
import urllib.request
from datetime import datetime, timezone


# Binance intl is geo-blocked from US; use Binance US
BINANCE_KLINES = "https://api.binance.us/api/v3/klines"
BINANCE_TICKER = "https://api.binance.us/api/v3/ticker/price"


def get_price_at_time(symbol, timestamp_ms, interval='1m'):
    """Get the candle at a specific timestamp."""
    url = f"{BINANCE_KLINES}?symbol={symbol}&interval={interval}&startTime={timestamp_ms}&limit=1"
    req = urllib.request.Request(url, headers={'User-Agent': 'Mozilla/5.0'})
    try:
        resp = urllib.request.urlopen(req, timeout=10)
        data = json.loads(resp.read())
        if data:
            return {
                'open_time': data[0][0],
                'open': float(data[0][1]),
                'high': float(data[0][2]),
                'low': float(data[0][3]),
                'close': float(data[0][4]),
                'volume': float(data[0][5]),
            }
    except Exception as e:
        print(f"Error fetching {symbol}: {e}")
    return None


def get_klines(symbol, interval='1h', start_time_ms=None, end_time_ms=None, limit=1000):
    """Get historical klines/candlestick data."""
    params = f"symbol={symbol}&interval={interval}&limit={limit}"
    if start_time_ms:
        params += f"&startTime={start_time_ms}"
    if end_time_ms:
        params += f"&endTime={end_time_ms}"
    
    url = f"{BINANCE_KLINES}?{params}"
    req = urllib.request.Request(url, headers={'User-Agent': 'Mozilla/5.0'})
    
    try:
        resp = urllib.request.urlopen(req, timeout=15)
        raw = json.loads(resp.read())
        return [{
            'open_time': k[0],
            'open': float(k[1]),
            'high': float(k[2]),
            'low': float(k[3]),
            'close': float(k[4]),
            'volume': float(k[5]),
            'close_time': k[6],
        } for k in raw]
    except Exception as e:
        print(f"Error fetching klines for {symbol}: {e}")
        return []


def get_all_klines(symbol, interval, start_time_ms, end_time_ms):
    """Paginate through all klines between two timestamps."""
    all_klines = []
    current_start = start_time_ms
    
    while current_start < end_time_ms:
        batch = get_klines(symbol, interval, current_start, end_time_ms)
        if not batch:
            break
        all_klines.extend(batch)
        current_start = batch[-1]['close_time'] + 1
        time.sleep(0.1)  # Rate limiting
    
    return all_klines


def get_current_price(symbol):
    """Get current price."""
    url = f"{BINANCE_TICKER}?symbol={symbol}"
    req = urllib.request.Request(url, headers={'User-Agent': 'Mozilla/5.0'})
    try:
        resp = urllib.request.urlopen(req, timeout=10)
        data = json.loads(resp.read())
        return float(data['price'])
    except Exception as e:
        print(f"Error fetching current price for {symbol}: {e}")
        return None


def normalize_symbol(ticker):
    """Convert signal ticker to Binance symbol format."""
    # Remove USDT suffix if present, then add it back
    ticker = ticker.upper().replace('USDT', '').replace('/', '')
    return f"{ticker}USDT"


def datetime_to_ms(dt_str):
    """Convert datetime string to milliseconds timestamp."""
    # Handle various formats
    for fmt in ['%Y-%m-%dT%H:%M:%S', '%Y-%m-%d %H:%M:%S', '%Y-%m-%d']:
        try:
            dt = datetime.strptime(dt_str, fmt).replace(tzinfo=timezone.utc)
            return int(dt.timestamp() * 1000)
        except ValueError:
            continue
    return None


if __name__ == '__main__':
    # Test with current signals
    for ticker in ['ASTERUSDT', 'HYPEUSDT']:
        symbol = normalize_symbol(ticker)
        price = get_current_price(symbol)
        print(f"{symbol}: ${price}")
        
        # Get last 24h of 1h candles
        now_ms = int(time.time() * 1000)
        day_ago = now_ms - (24 * 60 * 60 * 1000)
        klines = get_klines(symbol, '1h', day_ago, now_ms)
        if klines:
            highs = [k['high'] for k in klines]
            lows = [k['low'] for k in klines]
            print(f"  24h range: ${min(lows):.4f} - ${max(highs):.4f}")
            print(f"  Candles: {len(klines)}")
        print()
