#!/usr/bin/env python3
"""Utility script to fetch and store historical OHLCV data from Binance public API.

This script uses the PublicDataAdapter to fetch historical market data without
requiring API keys. Perfect for populating your database with historical data
for backtesting and analysis.

Usage:
    python scripts/fetch_historical_data.py --symbol BTC/USDT --timeframe 1h --days 30
    python scripts/fetch_historical_data.py --symbol ETH/USDT --timeframe 1d --days 365
"""

import sys
import argparse
from datetime import datetime, timedelta
from pathlib import Path

# Add src to path
sys.path.insert(0, str(Path(__file__).parent.parent))

from src.exchanges.public_data import PublicDataAdapter
from src.data.collector import get_data_collector
from src.core.logger import setup_logging, get_logger

setup_logging()
logger = get_logger(__name__)


def fetch_historical_data(
    symbol: str,
    timeframe: str,
    days: int,
    exchange_name: str = "Binance Public"
) -> int:
    """Fetch and store historical OHLCV data.
    
    Args:
        symbol: Trading symbol (e.g., 'BTC/USDT')
        timeframe: Timeframe (e.g., '1h', '1d', '4h')
        days: Number of days of historical data to fetch
        exchange_name: Exchange name for storage
    
    Returns:
        Number of candles stored
    """
    logger.info(f"Fetching {days} days of {timeframe} data for {symbol}")
    
    # Create public data adapter
    adapter = PublicDataAdapter()
    if not adapter.connect():
        logger.error("Failed to connect to Binance public API")
        return 0
    
    # Calculate start date
    end_date = datetime.utcnow()
    start_date = end_date - timedelta(days=days)
    
    # Fetch data in chunks (Binance limit is 1000 candles per request)
    collector = get_data_collector()
    total_candles = 0
    
    current_date = start_date
    chunk_days = 30  # Fetch 30 days at a time to stay under 1000 candle limit
    
    while current_date < end_date:
        chunk_end = min(current_date + timedelta(days=chunk_days), end_date)
        
        logger.info(f"Fetching data from {current_date.date()} to {chunk_end.date()}")
        
        # Fetch OHLCV data
        ohlcv = adapter.get_ohlcv(
            symbol=symbol,
            timeframe=timeframe,
            since=current_date,
            limit=1000
        )
        
        if ohlcv:
            # Store in database
            collector.store_ohlcv(exchange_name, symbol, timeframe, ohlcv)
            total_candles += len(ohlcv)
            logger.info(f"Stored {len(ohlcv)} candles (total: {total_candles})")
        else:
            logger.warning(f"No data returned for period {current_date} to {chunk_end}")
        
        # Move to next chunk
        current_date = chunk_end
        
        # Small delay to respect rate limits
        import time
        time.sleep(1)
    
    adapter.disconnect()
    logger.info(f"Completed! Total candles stored: {total_candles}")
    return total_candles


def main():
    """Main entry point."""
    parser = argparse.ArgumentParser(
        description="Fetch historical OHLCV data from Binance public API"
    )
    parser.add_argument(
        '--symbol',
        type=str,
        default='BTC/USDT',
        help='Trading symbol (e.g., BTC/USDT, ETH/USDT)'
    )
    parser.add_argument(
        '--timeframe',
        type=str,
        default='1h',
        choices=['1m', '5m', '15m', '30m', '1h', '4h', '1d', '1w'],
        help='Timeframe for candles'
    )
    parser.add_argument(
        '--days',
        type=int,
        default=30,
        help='Number of days of historical data to fetch'
    )
    parser.add_argument(
        '--exchange',
        type=str,
        default='Binance Public',
        help='Exchange name for storage (default: Binance Public)'
    )
    
    args = parser.parse_args()
    
    try:
        count = fetch_historical_data(
            symbol=args.symbol,
            timeframe=args.timeframe,
            days=args.days,
            exchange_name=args.exchange
        )
        print(f"\n✓ Successfully fetched and stored {count} candles")
        print(f"  Symbol: {args.symbol}")
        print(f"  Timeframe: {args.timeframe}")
        print(f"  Period: {args.days} days")
        return 0
    except KeyboardInterrupt:
        print("\n\nInterrupted by user")
        return 1
    except Exception as e:
        logger.error(f"Error: {e}", exc_info=True)
        print(f"\n✗ Error: {e}")
        return 1


if __name__ == '__main__':
    sys.exit(main())
