#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Script para visualizar en tiempo real las velas cerradas de un par de trading en Binance.

Autor: Salvador Pinon
Versión: 1.0
Fecha: 2025-05-07
Licencia: MIT

Descripción:
Este script utiliza la API de Binance para consultar y mostrar las últimas velas cerradas
(candlesticks) de un símbolo específico, y continúa monitoreando y mostrando nuevas velas
cerradas a medida que se generan en tiempo real.
"""

from binance.client import Client
from datetime import datetime
import argparse
import time
import logging
import os

# API credentials (replace with your actual Binance API key and secret)
API_KEY = ''  # Fill in your API key
API_SECRET = ''  # Fill in your API secret

# Initialize Binance client
client = Client(api_key=API_KEY, api_secret=API_SECRET)


def get_closed_klines(symbol, interval, count):
    """
    Retrieve the latest closed klines (candlesticks) from Binance.

    Parameters:
        symbol (str): The trading pair symbol (e.g., 'BTCUSDT').
        interval (str): The kline interval (e.g., '1m', '5m', '1h').
        count (int): Number of closed klines to retrieve.

    Returns:
        list: List of closed klines, excluding the current forming kline.
    """
    klines = client.get_klines(symbol=symbol.upper(), interval=interval, limit=count + 1)
    return klines[:-1]  # Exclude the current (still open) kline


def print_kline_table(klines):
    """
    Print a formatted table of klines with timestamp, open, high, low, close, and volume.

    Parameters:
        klines (list): List of klines to display.
    """
    for kline in klines:
        open_price = kline[1]
        high_price = kline[2]
        low_price = kline[3]
        close_price = kline[4]
        volume = kline[5]
        timestamp = int(kline[0]) // 1000
        kline_time = datetime.fromtimestamp(timestamp).strftime('%Y-%m-%d %H:%M:%S')
        print(f"{kline_time:<20} {open_price:<15} {high_price:<15} {low_price:<15} {close_price:<15} {volume:<15}")


def wait_for_new_closed_kline(symbol, interval, last_kline_open_time):
    """
    Continuously check for a new closed kline.

    Parameters:
        symbol (str): Trading pair symbol.
        interval (str): Kline interval.
        last_kline_open_time (int): Timestamp of the last known closed kline.

    Returns:
        list: The new closed kline once it becomes available.
    """
    while True:
        latest = client.get_klines(symbol=symbol, interval=interval, limit=2)[-2]
        if latest[0] != last_kline_open_time:
            return latest
        time.sleep(1)


def main():
    """
    Main function to parse arguments and display real-time closed candles for a given trading pair.
    """
    parser = argparse.ArgumentParser(
        description="Script that reads and displays closed candlesticks of a trading pair on Binance in real time. "
                    "Allows specifying the symbol, timeframe, and number of initial candles to display."
    )

    parser.add_argument('--exchange', type=str, default='binance', help='Exchange Name (e.g., Binance, Bybit, Kraken, etc.)')
    parser.add_argument('--symbol',   type=str, default='BTCUSDT', help='Trading pair (e.g., BTCUSDT)')
    parser.add_argument('--interval', type=str, default='1m',      help='Candle interval (e.g., 1m, 5m, 1h)')
    parser.add_argument('--limit',    type=int, default=20,        help='Number of initial candles to display')
    parser.add_argument('--kafkamonitor',   type=str, default='',        help='Kafka Topcic to monitor')

    args = parser.parse_args()

    exchange = args.exchange
    symbol = args.symbol.upper()
    interval = args.interval
    limit = args.limit
    kafkamonitor = args.kafkamonitor

    print(f"Initializing with the last {limit} closed candles for {symbol} ({interval})...\n")
    klines = get_closed_klines(symbol, interval, limit)
    print_kline_table(klines)

    last_kline_open_time = klines[-1][0]

    while True:
        print(f"\nWaiting for new closed candle for {symbol} / {exchange}...\n")
        new_closed_kline = wait_for_new_closed_kline(symbol, interval, last_kline_open_time)
        print("New closed candle detected:\n")
        print_kline_table([new_closed_kline])
        last_kline_open_time = new_closed_kline[0]


if __name__ == "__main__":
    main()
    # try:
    #     main()
    # except Exception as e:
    #     print(f"An error occurred: {e}")
