import math
import os.path
from datetime import datetime

import pandas as pd
from binance.client import Client
from bitmex import bitmex
from dateutil import parser

### API
bitmex_api_key = 'DIQWYpC_OiU-TyCFNKohNu7t'  # Enter your own API-key here
bitmex_api_secret = 'sjpLLCl29pI5RdX2WOjdXgk8BgW2blaTTqazqUgpmO_Hy0-u'  # Enter your own API-secret here
binance_api_key = 'JxzTHMdxIgeO4ou99Q35JaGfnbCJj1EpXtfWABBLQCsqs85Srll74dqjlI3ctROC'  # Enter your own API-key here
binance_api_secret = '9gfLmkHIyI5oyzLSA6sNQWTHHcT7I8qjomhWqWL66xIuDqTBmIq7gO1IKkOi7iOT'  # Enter your own API-secret here

### CONSTANTS
binsizes = {"1m": 1, "5m": 5, "1h": 60,
            "1d": 1440}  # Tutaj masz interwał czasowy jaki możsez wpisać sobie jako argument funkcji
batch_size = 750
bitmex_client = bitmex(test=False, api_key=bitmex_api_key, api_secret=bitmex_api_secret)
binance_client = Client(api_key=binance_api_key, api_secret=binance_api_secret)


### FUNCTIONS
def minutes_of_new_data(symbol, kline_size, data, source):
    if len(data) > 0:
        old = parser.parse(data["timestamp"].iloc[-1])
    elif source == "binance":
        old = datetime.strptime('1 Jan 2019', '%d %b %Y')
    elif source == "bitmex":
        old = \
        bitmex_client.Trade.Trade_getBucketed(symbol=symbol, binSize=kline_size, count=1, reverse=False).result()[0][0][
            'timestamp']
    if source == "binance": new = pd.to_datetime(binance_client.get_klines(symbol=symbol, interval=kline_size)[-1][0],
                                                 unit='ms')
    if source == "bitmex": new = \
    bitmex_client.Trade.Trade_getBucketed(symbol=symbol, binSize=kline_size, count=1, reverse=True).result()[0][0][
        'timestamp']
    return old, new


def get_all_binance(symbol, kline_size, save=False):
    filename = '%s-%s-data.csv' % (symbol, kline_size)
    if os.path.isfile(filename):
        data_df = pd.read_csv(filename)
    else:
        data_df = pd.DataFrame()
    oldest_point, newest_point = minutes_of_new_data(symbol, kline_size, data_df, source="binance")

    delta_min = (newest_point - oldest_point).total_seconds() / 60
    available_data = math.ceil(delta_min / binsizes[kline_size])

    if oldest_point == datetime.strptime('1 Jan 2018', '%d %b %Y'):
        print('Downloading all available %s data for %s. Be patient..!' % (kline_size, symbol))
    else:
        print('Downloading %d minutes of new data available for %s, i.e. %d instances of %s data.' % (
        delta_min, symbol, available_data, kline_size))
        klines = binance_client.get_historical_klines(symbol, kline_size, oldest_point.strftime("%d %b %Y %H:%M:%S"),
                                                      newest_point.strftime("%d %b %Y %H:%M:%S"))
        data = pd.DataFrame(klines,
                            columns=['timestamp', 'open', 'high', 'low', 'close', 'volume', 'close_time', 'quote_av',
                                     'trades', 'tb_base_av', 'tb_quote_av', 'ignore'])
        data['timestamp'] = pd.to_datetime(data['timestamp'], unit='ms')

    if len(data_df) > 0:
        temp_df = pd.DataFrame(data)
        data_df = data_df.append(temp_df)
    else:
        data_df = data
    data_df.set_index('timestamp', inplace=True)

    if save: data_df.to_csv(filename)
    print('All caught up..!' + '[' + symbol + ']')

    return data_df
