import requests
import ccxt
import schedule
import time
from binance.client import Client
from dotenv import load_dotenv
import os

# ✅ Toggle between test mode and scheduled mode
TEST_MODE = False  # Set to False to activate scheduled run (once daily at 9:00 AM)

# --- Load environment variables ---
load_dotenv()
api_key = os.getenv("BINANCE_API_KEY", "YOUR_BINANCE_API_KEY")
api_secret = os.getenv("BINANCE_API_SECRET", "YOUR_BINANCE_API_SECRET")
TELEGRAM_BOT_TOKEN = os.getenv("TELEGRAM_BOT_TOKEN")
TELEGRAM_CHAT_ID = os.getenv("TELEGRAM_CHAT_ID")
DISCORD_WEBHOOK_URL = os.getenv("DISCORD_WEBHOOK_URL")

# ✅ Telegram Alert
def send_telegram_message(message):
    url = f'https://api.telegram.org/bot{TELEGRAM_BOT_TOKEN}/sendMessage'
    payload = {
        'chat_id': TELEGRAM_CHAT_ID,
        'text': message,
        'parse_mode': 'HTML'
    }
    try:
        requests.post(url, json=payload)
    except Exception as e:
        print(f"⚠️ Failed to send Telegram message: {e}")

# ✅ Discord Alert
def send_discord_message(message):
    payload = {
        "content": message
    }
    try:
        requests.post(DISCORD_WEBHOOK_URL, json=payload)
    except Exception as e:
        print(f"⚠️ Failed to send Discord message: {e}")

# ✅ Initialize Binance Spot Client
client = Client(api_key, api_secret)

# ✅ Test API Key
try:
    account_info = client.get_account()
    print("\n✅ Binance API Key Test: SUCCESS - Connected to your account.")
except Exception as e:
    print("\n❌ Binance API Key Test: FAILED")
    print(f"  - Error: {e}")

# ✅ Compare Spot Prices Across Exchanges
def check_exchange_arbitrage(symbol, prices, threshold=0.001):  # 0.1% threshold
    print(f"\n📊 Arbitrage Opportunities for {symbol}")
    exchanges = list(prices.keys())
    found = False

    for i in range(len(exchanges)):
        for j in range(i + 1, len(exchanges)):
            ex1, ex2 = exchanges[i], exchanges[j]
            price1, price2 = prices[ex1], prices[ex2]

            if price1 <= 0 or price2 <= 0:
                continue

            margin1 = (price2 - price1) / price1
            margin2 = (price1 - price2) / price2

            if margin1 > threshold:
                found = True
                print(f"💰 Buy from {ex1} at {price1}, Sell to {ex2} at {price2} | Profit: {margin1:.2%}")
                message = (
                    f"🚨 *Arbitrage Opportunity*\n"
                    f"Symbol: **{symbol}**\n"
                    f"Buy from: **{ex1}** at `{price1:.2f}`\n"
                    f"Sell to: **{ex2}** at `{price2:.2f}`\n"
                    f"Profit Margin: **{margin1:.2%}**"
                )
                send_telegram_message(message)
                send_discord_message(message)

            elif margin2 > threshold:
                found = True
                print(f"💰 Buy from {ex2} at {price2}, Sell to {ex1} at {price1} | Profit: {margin2:.2%}")
                message = (
                    f"🚨 *Arbitrage Opportunity*\n"
                    f"Symbol: **{symbol}**\n"
                    f"Buy from: **{ex2}** at `{price2:.2f}`\n"
                    f"Sell to: **{ex1}** at `{price1:.2f}`\n"
                    f"Profit Margin: **{margin2:.2%}**"
                )
                send_telegram_message(message)
                send_discord_message(message)

    if not found:
        print("⚠️ No arbitrage opportunities found above threshold.")

# ✅ Arbitrage Check Across Exchanges
def get_arbitrage_prices(symbols=None):
    if symbols is None:
        symbols = ["BTC/USDT", "ETH/USDT", "XRP/USDT", "SOL/USDT"]

    exchanges = {
        "Binance": ccxt.binance(),
        "Kraken": ccxt.kraken(),
        "KuCoin": ccxt.kucoin(),
        "Bitfinex": ccxt.bitfinex(),
        "Bybit": ccxt.bybit(),
        "Coinbase": ccxt.coinbase(),
        "OKX": ccxt.okx(),
        "Gate.io": ccxt.gateio(),
        "Huobi": ccxt.huobi()
    }

    print("\n🔍 Running Exchange-to-Exchange Arbitrage Scan")
    for symbol in symbols:
        print(f"\n--- {symbol} ---")
        prices = {}

        for name, ex in exchanges.items():
            try:
                ticker = ex.fetch_ticker(symbol)
                prices[name] = ticker["last"]
                print(f"{name:8}: {prices[name]}")
            except Exception as e:
                print(f"⚠️ {name:8} - Error: {e}")

        if prices:
            check_exchange_arbitrage(symbol, prices, threshold=0.001)
        else:
            print(f"⚠️ No prices available for {symbol}.")

# ✅ Toggle Between Test Mode and Scheduler
if TEST_MODE:
    print("🚀 Running arbitrage scan immediately (TEST_MODE enabled)")
    get_arbitrage_prices()
else:
    schedule.every().day.at("09:00").do(get_arbitrage_prices)
    print("📆 Arbitrage scanner is running once daily at 9:00 AM.")
    while True:
        schedule.run_pending()
        time.sleep(30)

