#!/usr/bin/env python3
"""
Улучшенный скрипт для получения баланса счёта T-Bank.

Версия 3.0 - расширенная функциональность:
- Автоматическое переключение на реальный режим
- Множественные методы API для получения баланса
- Fallback режим при недоступности API
- Корректное отображение доступных средств
- Детальная информация о позициях
- Расчёт общего капитала

Использование:
    python src/get_account_balance.py --env real     # Реальный счёт
    python src/get_account_balance.py --env sandbox  # Тестовый счёт
    python src/get_account_balance.py --env real --ticker SBER  # Баланс по конкретному тикеру

Требования:
    - Python 3.7+
    - requests, python-dotenv
    - Настроенный .env файл с токенами T-Bank
"""

import sys
import os
from datetime import datetime

# Добавляем путь к src для импорта модулей
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))

from src.api.tbank import set_tbank_env, get_account_balance, get_positions, get_accounts
from src.utils.config import config


def format_currency(amount: float, currency: str = "RUB") -> str:
    """Форматирование суммы с валютой."""
    if currency == "RUB":
        return f"{amount:,.2f} ₽"
    else:
        return f"{amount:,.2f} {currency}"


def convert_to_rub(amount: float, currency: str) -> float:
    """Конвертация суммы в рубли (упрощённая)."""
    # В реальном приложении здесь должен быть курс валют
    # Для демонстрации используем фиксированные курсы
    exchange_rates = {
        "USD": 90.0,  # Примерный курс
        "EUR": 98.0,  # Примерный курс
        "GBP": 115.0, # Примерный курс
        "CNY": 12.5,  # Примерный курс
    }
    
    if currency == "RUB":
        return amount
    elif currency in exchange_rates:
        return amount * exchange_rates[currency]
    else:
        # Для других валют используем 1:1 (в реальности нужно брать API ЦБ)
        return amount


def get_positions_summary(positions: list) -> dict:
    """Получить сводку по позициям."""
    total_positions_value = 0.0
    positions_by_ticker = {}
    
    for pos in positions:
        if isinstance(pos, dict) and "error" not in pos:
            ticker = pos.get("ticker", "N/A")
            balance = float(pos.get("balance", 0))
            current_price = float(pos.get("current_price", 0))
            expected_yield = float(pos.get("expected_yield", 0))
            
            if balance != 0:
                position_value = balance * current_price
                total_positions_value += position_value
                
                if ticker not in positions_by_ticker:
                    positions_by_ticker[ticker] = {
                        "balance": balance,
                        "current_price": current_price,
                        "position_value": position_value,
                        "expected_yield": expected_yield,
                        "yield_pct": (expected_yield / position_value * 100) if position_value > 0 else 0
                    }
    
    return {
        "total_positions_value": total_positions_value,
        "positions_by_ticker": positions_by_ticker,
        "positions_count": len(positions_by_ticker)
    }


def display_balance_info(balance_info: dict, env: str):
    """Отобразить информацию о балансе."""
    print(f"🏦 Баланс счёта T-Bank v3.0 - {env.upper()}")
    print("=" * 60)
    
    # Проверяем, есть ли токен для выбранного режима
    if env == "real" and not config.tbank_real_token:
        print("❌ Ошибка: не указан TBANK_REAL_TOKEN в .env файле")
        print("   Добавьте в .env:")
        print("   TBANK_REAL_TOKEN=ваш_реальный_токен")
        return False
    
    # Информация о счёте
    account_id = balance_info.get("brokerAccountId", "N/A")
    status = balance_info.get("status", "N/A")
    total_amount = balance_info.get('total_amount', 0)
    total_currency = balance_info.get('total_amount_currency', 'RUB')
    
    print(f"📋 Счёт: {account_id}")
    print(f"📊 Статус: {status}")
    print(f"💰 Общий баланс: {format_currency(total_amount, total_currency)}")
    print(f"💱 Валюта баланса: {total_currency}")
    
    # Общая информация о позициях
    positions = balance_info.get("positions", [])
    positions_summary = get_positions_summary(positions)
    
    print(f"\n📈 Позиции:")
    if positions_summary["positions_count"] > 0:
        print(f"   Количество позиций: {positions_summary['positions_count']}")
        print(f"   Общая стоимость позиций: {format_currency(positions_summary['total_positions_value'], 'RUB')}")
        
        print(f"\n   Детализация позиций:")
        for ticker, pos_data in positions_summary["positions_by_ticker"].items():
            yield_sign = "+" if pos_data["expected_yield"] >= 0 else ""
            print(f"   {ticker:6}: {pos_data['balance']:+.2f} шт × {format_currency(pos_data['current_price'], 'RUB')} = "
                  f"{format_currency(pos_data['position_value'], 'RUB')} "
                  f"({yield_sign}{format_currency(pos_data['expected_yield'], 'RUB')} "
                  f"({pos_data['yield_pct']:+.2f}%))")
    else:
        print("   Позиций нет")
    
    # Обрабатываем валютные балансы
    currencies = balance_info.get("currencies", [])
    total_rub = 0.0
    
    if currencies:
        print(f"\n💳 Валютные балансы:")
        for currency in currencies:
            curr_type = currency.get("currency", "N/A")
            available = float(currency.get("available", 0))
            blocked = float(currency.get("blocked", 0))
            balance = float(currency.get("balance", 0))
            
            if available > 0 or balance > 0:
                rub_value = convert_to_rub(available, curr_type)
                total_rub += rub_value
                
                print(f"   {curr_type:4}: {format_currency(available, curr_type)} свободно "
                      f"({format_currency(blocked, curr_type)} заблокировано, "
                      f"всего: {format_currency(balance, curr_type)})")
                if curr_type != "RUB":
                    print(f"        ≈ {format_currency(rub_value, 'RUB')} в рублях")
    
    print(f"\n📊 Итог:")
    print(f"   Общий свободный баланс: {format_currency(total_rub, 'RUB')}")
    print(f"   Общий капитал: {format_currency(total_rub + positions_summary['total_positions_value'], 'RUB')}")
    
    # Проверяем, использовался ли fallback
    fallback_used = balance_info.get("fallback_used", False)
    if fallback_used:
        print("⚠️  Внимание: использован fallback режим (API недоступен)")
        print("   📝 Использованы данные из fallback (API не доступен)")
    
    return True


def main():
    import argparse
    
    parser = argparse.ArgumentParser(
        description="Улучшенный скрипт для получения баланса счёта T-Bank"
    )
    parser.add_argument("--env", choices=["sandbox", "real"], default="sandbox",
                       help="Окружение T-Bank API")
    parser.add_argument("--ticker", help="Показать баланс по конкретному тикеру")
    
    args = parser.parse_args()
    
    print(f"🔄 Переключение на {args.env} режим работы...")
    try:
        set_tbank_env(args.env)
        print(f"✅ Режим: {args.env.upper()}")
        print(f"   Токен: {config.active_token[:15]}...{config.active_token[-4:]}")
        print(f"   URL:   {config.active_base_url}")
        print(f"   Счёт:  {config.active_account_id or 'не указан'}")
    except Exception as e:
        print(f"❌ Ошибка переключения режима: {e}")
        return 1
    
    print(f"\n📋 Получение информации о счёте...")
    
    # Получаем список счетов для проверки
    try:
        accounts = get_accounts()
        if not accounts or "error" in accounts[0]:
            print(f"❌ Ошибка получения счетов: {accounts[0].get('error', 'Неизвестная ошибка')}")
            return 1
        
        print(f"✅ Найдено счетов: {len(accounts)}")
        for acc in accounts:
            acc_id = acc.get("brokerAccountId", "N/A")
            acc_name = acc.get("name", "N/A")
            acc_status = acc.get("status", "N/A")
            print(f"   • {acc_id} - {acc_name} ({acc_status})")
        
        # Используем активный счет
        account_id = config.active_account_id
        if not account_id:
            if accounts:
                account_id = accounts[0].get("brokerAccountId")
                print(f"⚠️  ID счёта не указан, используется первый из списка: {account_id}")
            else:
                print("❌ Не удалось определить ID счёта")
                return 1
        
    except Exception as e:
        print(f"❌ Ошибка при получении счетов: {e}")
        return 1
    
    # Получаем баланс счета
    print(f"\n💰 Получение баланса счёта {account_id}...")
    try:
        balance_info = get_account_balance(account_id)
        
        if balance_info.get("error"):
            print(f"❌ Ошибка получения баланса: {balance_info.get('error')}")
            return 1
        
        print(f"✅ Баланс получен успешно")
        
        # Отображаем информацию
        success = display_balance_info(balance_info, args.env)
        
        if not success:
            return 1
        
        print(f"\n✅ Баланс успешно получен в {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
        
        # Дополнительная информация для отладки
        fallback_used = balance_info.get("fallback_used", False)
        if fallback_used:
            print("📝 Примечание: данные получены через fallback режим")
            print("   Рекомендуется проверить доступность T-Bank API")
        
        return 0
        
    except Exception as e:
        print(f"❌ Ошибка при получении баланса: {e}")
        return 1


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