#!/usr/bin/env python3
"""
Diagnostic de connexion Binance
================================
Teste la connexion API Binance et identifie les problèmes
"""

import sys
import os
from datetime import datetime

# Ajouter le répertoire courant au path
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, SCRIPT_DIR)

try:
    from binance.client import Client
    from binance.exceptions import BinanceAPIException
    from config import BINANCE_API_KEY, BINANCE_API_SECRET, TESTNET_MODE
except ImportError as e:
    print(f"❌ Erreur d'import: {e}")
    print("   Installe les dépendances: pip install python-binance")
    sys.exit(1)

def test_api_keys():
    """Vérifie que les clés API sont configurées"""
    print("\n" + "="*70)
    print("🔑 VÉRIFICATION DES CLÉS API")
    print("="*70)
    
    if not BINANCE_API_KEY or not BINANCE_API_SECRET:
        print("❌ ERREUR: Clés API manquantes dans config.py")
        return False
    
    # Vérifier que les clés ne sont pas vides ou par défaut
    if BINANCE_API_KEY == "your_api_key_here" or BINANCE_API_SECRET == "your_api_secret_here":
        print("❌ ERREUR: Les clés API sont toujours aux valeurs par défaut")
        print("   Remplace-les dans config.py avec tes vraies clés")
        return False
    
    print(f"✅ Clé API trouvée: {BINANCE_API_KEY[:8]}...{BINANCE_API_KEY[-8:]}")
    print(f"✅ Secret trouvé: {BINANCE_API_SECRET[:8]}...***")
    print(f"✅ Mode: {'TESTNET (argent fictif)' if TESTNET_MODE else '⚠️ PRODUCTION (argent réel)'}")
    
    return True

def test_binance_connection():
    """Teste la connexion à Binance"""
    print("\n" + "="*70)
    print("🌐 TEST DE CONNEXION BINANCE")
    print("="*70)
    
    try:
        # Créer le client Binance
        print(f"   Connexion au serveur: {'Testnet' if TESTNET_MODE else 'Production'}...")
        client = Client(
            api_key=BINANCE_API_KEY,
            api_secret=BINANCE_API_SECRET,
            testnet=TESTNET_MODE
        )
        
        # Test 1: Récupérer l'heure du serveur
        print("\n1️⃣ Test de l'heure du serveur...")
        try:
            server_time = client.get_server_time()
            server_timestamp = server_time['serverTime']
            server_date = datetime.fromtimestamp(server_timestamp / 1000)
            print(f"   ✅ Serveur accessible: {server_date.strftime('%Y-%m-%d %H:%M:%S')}")
        except Exception as e:
            print(f"   ❌ Serveur inaccessible: {e}")
            return False
        
        # Test 2: Récupérer les informations du compte (nécessite authentification)
        print("\n2️⃣ Test d'authentification API...")
        try:
            account = client.get_account()
            print(f"   ✅ Authentification réussie!")
            print(f"   📊 Type de compte: {account.get('accountType', 'N/A')}")
            print(f"   📊 Peut trader: {account.get('canTrade', False)}")
            print(f"   📊 Peut retirer: {account.get('canWithdraw', False)}")
            print(f"   📊 Peut déposer: {account.get('canDeposit', False)}")
            
            # Afficher les balances
            print("\n💰 BALANCES:")
            balances = account.get('balances', [])
            non_zero = [b for b in balances if float(b['free']) > 0 or float(b['locked']) > 0]
            
            if non_zero:
                for balance in non_zero[:10]:  # Limiter à 10
                    free = float(balance['free'])
                    locked = float(balance['locked'])
                    total = free + locked
                    if total > 0:
                        print(f"   {balance['asset']:>6}: {total:>15.8f} (libre: {free:.8f}, bloqué: {locked:.8f})")
            else:
                print("   ⚠️ Aucune balance trouvée (normal pour un nouveau compte testnet)")
            
        except BinanceAPIException as e:
            print(f"   ❌ Erreur d'authentification: {e}")
            print(f"   Code erreur: {e.code}")
            print(f"   Message: {e.message}")
            
            if e.code == -2015:
                print("\n⚠️ ERREUR -2015: Clé API invalide, IP non autorisée, ou permissions manquantes")
                print("\n📋 SOLUTIONS POSSIBLES:")
                print("   1. Vérifie que tes clés API sont correctes dans config.py")
                print("   2. Sur Binance Testnet (https://testnet.binance.vision/):")
                print("      - Connecte-toi avec ton compte testnet")
                print("      - Crée une nouvelle clé API si nécessaire")
                print("      - Copie la clé et le secret dans config.py")
                print("   3. Vérifie les permissions de la clé API:")
                print("      - Enable Reading (lecture)")
                print("      - Enable Spot & Margin Trading (trading)")
                print("   4. Restrictions IP:")
                print("      - Sur le testnet, généralement pas de restriction IP")
                print("      - Vérifie que 'Unrestricted' est activé")
                print("   5. Si tu utilises un VPN, essaie de le désactiver")
            
            return False
        
        # Test 3: Récupérer un prix (test de lecture publique)
        print("\n3️⃣ Test de récupération des prix...")
        try:
            ticker = client.get_symbol_ticker(symbol="BTCUSDT")
            price = float(ticker['price'])
            print(f"   ✅ Prix BTC: {price:,.2f} USDT")
        except Exception as e:
            print(f"   ❌ Erreur récupération prix: {e}")
            return False
        
        # Test 4: Récupérer les ordres ouverts (nécessite authentification + permissions)
        print("\n4️⃣ Test de lecture des ordres...")
        try:
            orders = client.get_open_orders()
            print(f"   ✅ Ordres ouverts accessibles: {len(orders)} ordre(s)")
        except BinanceAPIException as e:
            print(f"   ❌ Erreur lecture ordres: {e}")
            if e.code == -2015:
                print("   ⚠️ Permissions insuffisantes (normal si clés en lecture seule)")
            return False
        
        print("\n" + "="*70)
        print("✅ TOUS LES TESTS RÉUSSIS!")
        print("="*70)
        return True
        
    except Exception as e:
        print(f"\n❌ ERREUR CRITIQUE: {e}")
        import traceback
        traceback.print_exc()
        return False

def check_network():
    """Vérifie la connectivité réseau"""
    print("\n" + "="*70)
    print("🌍 VÉRIFICATION RÉSEAU")
    print("="*70)
    
    import socket
    
    # Tester la résolution DNS
    hosts = [
        ("testnet.binance.vision", 443),
        ("api.binance.com", 443),
    ]
    
    for host, port in hosts:
        try:
            socket.create_connection((host, port), timeout=5)
            print(f"   ✅ {host}:{port} accessible")
        except Exception as e:
            print(f"   ❌ {host}:{port} inaccessible: {e}")

def main():
    """Fonction principale"""
    print("\n" + "="*70)
    print("🔧 DIAGNOSTIC COMPLET BINANCE API")
    print("="*70)
    
    # Vérifier les clés
    if not test_api_keys():
        return 1
    
    # Vérifier le réseau
    check_network()
    
    # Tester la connexion Binance
    if test_binance_connection():
        print("\n✅ La connexion Binance fonctionne correctement!")
        print("   Tu peux lancer le bot en toute sécurité.")
        return 0
    else:
        print("\n❌ Problème de connexion détecté.")
        print("   Corrige les erreurs ci-dessus avant de lancer le bot.")
        return 1

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