#!/usr/bin/env python3
"""
Synchronisation et diagnostic des positions Binance
====================================================
Vérifie et synchronise les positions entre le bot et Binance
"""

import sys
import os
import json
from datetime import datetime
from decimal import Decimal

# 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}")
    sys.exit(1)

# Fichiers de données
POSITIONS_FILE = os.path.join(SCRIPT_DIR, "positions.json")
TRADE_HISTORY_FILE = os.path.join(SCRIPT_DIR, "trade_history.json")

def load_local_positions():
    """Charger les positions locales"""
    if os.path.exists(POSITIONS_FILE):
        try:
            with open(POSITIONS_FILE, 'r', encoding='utf-8') as f:
                data = json.load(f)
                return data if isinstance(data, dict) else {}
        except Exception as e:
            print(f"⚠️ Erreur lecture positions locales: {e}")
    return {}

def save_local_positions(positions):
    """Sauvegarder les positions locales"""
    try:
        with open(POSITIONS_FILE, 'w', encoding='utf-8') as f:
            json.dump(positions, f, indent=2, ensure_ascii=False)
        return True
    except Exception as e:
        print(f"❌ Erreur sauvegarde positions: {e}")
        return False

def get_binance_balances(client):
    """Récupérer les balances Binance (SPOT)"""
    try:
        account = client.get_account()
        balances = {}
        
        for balance in account.get('balances', []):
            asset = balance['asset']
            free = float(balance['free'])
            locked = float(balance['locked'])
            total = free + locked
            
            # Ne garder que les balances non nulles (sauf USDT qu'on garde toujours)
            if total > 0 or asset == 'USDT':
                balances[asset] = {
                    'free': free,
                    'locked': locked,
                    'total': total
                }
        
        return balances
    except BinanceAPIException as e:
        print(f"❌ Erreur API Binance: {e}")
        if e.code == -2015:
            print("⚠️ Problème d'authentification - vérifie tes clés API")
        return None
    except Exception as e:
        print(f"❌ Erreur inattendue: {e}")
        return None

def get_current_price(client, symbol):
    """Récupérer le prix actuel d'un symbole"""
    try:
        ticker = client.get_symbol_ticker(symbol=symbol)
        return float(ticker['price'])
    except:
        return None

def main():
    """Fonction principale"""
    print("\n" + "="*80)
    print("🔄 SYNCHRONISATION ET DIAGNOSTIC DES POSITIONS")
    print("="*80)
    
    # Créer le client Binance
    print(f"\n📡 Connexion à Binance {'Testnet' if TESTNET_MODE else 'Production'}...")
    try:
        client = Client(
            api_key=BINANCE_API_KEY,
            api_secret=BINANCE_API_SECRET,
            testnet=TESTNET_MODE
        )
        print("   ✅ Connecté")
    except Exception as e:
        print(f"   ❌ Erreur connexion: {e}")
        return 1
    
    # Charger les positions locales
    print("\n📁 Chargement des positions locales...")
    local_positions = load_local_positions()
    print(f"   Positions locales: {len(local_positions)}")
    
    if local_positions:
        print("\n   Positions enregistrées:")
        for symbol, pos in local_positions.items():
            print(f"      • {symbol}: {pos.get('quantity', 0)} @ {pos.get('entry_price', 0)} USDT")
    
    # Récupérer les balances Binance
    print("\n💰 Récupération des balances Binance...")
    binance_balances = get_binance_balances(client)
    
    if binance_balances is None:
        print("   ❌ Impossible de récupérer les balances")
        return 1
    
    print(f"   ✅ {len(binance_balances)} actifs trouvés")
    
    # Afficher les balances principales
    print("\n   Balances principales:")
    usdt_balance = binance_balances.get('USDT', {}).get('total', 0)
    print(f"      💵 USDT: {usdt_balance:,.2f} (libre: {binance_balances.get('USDT', {}).get('free', 0):,.2f})")
    
    # Actifs crypto (non USDT)
    crypto_balances = {k: v for k, v in binance_balances.items() if k != 'USDT' and v['total'] > 0}
    
    if crypto_balances:
        print("\n   Cryptos détenues:")
        total_value_usdt = 0
        
        for asset, balance in sorted(crypto_balances.items()):
            symbol = f"{asset}USDT"
            current_price = get_current_price(client, symbol)
            
            if current_price:
                value_usdt = balance['total'] * current_price
                total_value_usdt += value_usdt
                print(f"      • {asset:>6}: {balance['total']:>15.8f} @ {current_price:>10.2f} = {value_usdt:>10.2f} USDT")
            else:
                print(f"      • {asset:>6}: {balance['total']:>15.8f} (prix indisponible)")
        
        print(f"\n   💎 Valeur totale des cryptos: {total_value_usdt:,.2f} USDT")
        print(f"   💰 Capital total: {usdt_balance + total_value_usdt:,.2f} USDT")
    else:
        print("      ℹ️ Aucune crypto détenue (uniquement USDT)")
    
    # Comparaison positions locales vs Binance
    print("\n" + "="*80)
    print("🔍 COMPARAISON POSITIONS LOCALES VS BINANCE")
    print("="*80)
    
    if not local_positions:
        print("✅ Aucune position locale enregistrée")
        if crypto_balances:
            print(f"⚠️ Mais {len(crypto_balances)} crypto(s) trouvée(s) sur Binance:")
            for asset in crypto_balances.keys():
                print(f"   • {asset}")
            print("\n💡 Ces cryptos ne sont pas trackées par le bot")
    else:
        # Vérifier chaque position locale
        positions_ok = 0
        positions_missing = 0
        
        for symbol, pos in local_positions.items():
            asset = symbol.replace('USDT', '')
            
            if asset in binance_balances:
                binance_qty = binance_balances[asset]['total']
                local_qty = pos.get('quantity', 0)
                
                if abs(binance_qty - local_qty) < 0.00001:
                    positions_ok += 1
                    print(f"✅ {symbol}: Synchronisé ({local_qty})")
                else:
                    print(f"⚠️ {symbol}: Différence - Local: {local_qty}, Binance: {binance_qty}")
            else:
                positions_missing += 1
                print(f"❌ {symbol}: Enregistré localement mais absent sur Binance")
        
        print(f"\n📊 Résumé: {positions_ok} OK, {positions_missing} manquantes")
    
    # Vérifier les cryptos sur Binance non trackées
    if crypto_balances:
        untracked = []
        for asset in crypto_balances.keys():
            symbol = f"{asset}USDT"
            if symbol not in local_positions:
                untracked.append(asset)
        
        if untracked:
            print(f"\n⚠️ {len(untracked)} crypto(s) sur Binance non trackée(s) par le bot:")
            for asset in untracked:
                print(f"   • {asset}")
    
    print("\n" + "="*80)
    print("✅ SYNCHRONISATION OK")
    print("="*80)
    print("\n💡 ÉTAT ACTUEL:")
    print(f"   • Positions locales: {len(local_positions)}")
    print(f"   • Cryptos sur Binance: {len(crypto_balances)}")
    print(f"   • Capital USDT: {usdt_balance:,.2f}")
    print(f"   • Connexion API: ✅ Opérationnelle")
    
    return 0

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