# coding=utf-8
import ujson
#from binance.websocket.spot.websocket_client import SpotWebsocketClient as WebsocketClient
from binance.spot import Spot
import time
import requests
import datetime
import pymysql
import math
#import pymongo

g_btcusdt_prices = {}
g_ethusdt_prices = {}

class ZoneDbIf:
    def __init__(self, host="172.17.0.1", port=4423, user="root", password="2GS@bPYcgiMyL14A", dbname="btcdb"):
        self.conn = pymysql.connect(host=host, port=port, user=user, password=password, database=dbname, cursorclass=pymysql.cursors.DictCursor)
        print("init  zone db suceess!")

    def save_zone_change(self, dayutc, change_us, change_asia, change_eu):
        with self.conn.cursor() as cursor:
            print(
            dayutc, change_us, change_asia, change_eu)
            sql_insert = "REPLACE INTO btczonechange3 (unixdt, change_us, change_asia, change_eu"
            sql_insert = sql_insert + ") VALUES (FROM_UNIXTIME(%s), %s, %s, %s)"
            cursor.execute(sql_insert, (
                dayutc, change_us, change_asia, change_eu))
        self.conn.commit()

class EthZoneDbIf:
    def __init__(self, host="172.17.0.1", port=4423, user="root", password="2GS@bPYcgiMyL14A", dbname="ethdb"):
        self.conn = pymysql.connect(host=host, port=port, user=user, password=password, database=dbname, cursorclass=pymysql.cursors.DictCursor)
        print("init zone db suceess!")

    def save_zone_change(self, dayutc, change_us, change_asia, change_eu):
        with self.conn.cursor() as cursor:
            print(
            dayutc, change_us, change_asia, change_eu)
            sql_insert = "REPLACE INTO ethzonechange3 (unixdt, change_us, change_asia, change_eu"
            sql_insert = sql_insert + ") VALUES (FROM_UNIXTIME(%s), %s, %s, %s)"
            cursor.execute(sql_insert, (
                dayutc, change_us, change_asia, change_eu))
        self.conn.commit()

def get_history_price(spot_client, pair_name):
    result = spot_client.klines(pair_name, "1h", limit=1000)
    prices_open = {}
    prices_close = {}
    for price in result:
        prices_open[str(price[0])] = float(price[1])
        prices_close[str(price[0])] = float(price[4])
    open_out = sorted(prices_open.items(), reverse=True)
    close_out = sorted(prices_close.items(), reverse=True)
    return open_out, close_out, prices_open, prices_close

def get_last_price(spot_client, pair_name, cache_open, cache_close):
    result = spot_client.klines(pair_name, "1h", limit=1)
    for price in result:
        cache_open[str(price[0])] = float(price[1])
        cache_close[str(price[0])] = float(price[4])
    open_out = sorted(cache_open.items(), reverse=True)
    close_out = sorted(cache_close.items(), reverse=True)
    return open_out, close_out, cache_open, cache_close

def calc_zone(prices_open, price_close, zone_start, zone_end):
    zone_total = 30*24
    zone_hours = 0
    zones = {}
    price_start = 0
    price_end = 0
    dt_start = None
    item_idx = 0
    for dt in prices_open:
        tobj = time.gmtime(int(dt[0]) / 1000)
        if tobj.tm_hour == zone_start:
            price_start = dt[1]
            dt_start = tobj
        if zone_hours == 0 and tobj.tm_hour < zone_end:
            zone_total = zone_total + tobj.tm_hour + 1
            close_list = price_close[item_idx]
            price_end = close_list[1]
        else:
            if tobj.tm_hour == zone_end:
                close_list = price_close[item_idx]
                price_end = close_list[1]
        if price_start > 0 and price_end > 0:
            #zones[dt_end] = (price_end-price_start)/price_start
            daystr = time.strftime("%d %b %Y", dt_start)
            dayutc = int(time.mktime(time.strptime(daystr, "%d %b %Y")))
            zones[str(dayutc)] = price_end - price_start
            price_start = 0
            price_end = 0
        item_idx = item_idx + 1
        zone_hours = zone_hours + 1
        if zone_hours >= zone_total:
            break
    return zones



def check_zone():
    dbif = ZoneDbIf()
    ethdbif = EthZoneDbIf()
    spot_client = Spot()
    prices_open, prices_close, cache_open, cache_close = get_history_price(spot_client, "BTCUSDT")
    prices_open_eth, prices_close_eth, cache_open_eth, cache_close_eth = get_history_price(spot_client, "ETHUSDT")
    prev_tm = time.gmtime(time.time())
    print("update", prev_tm.tm_hour)
    while True:
        zone_asia = calc_zone(prices_open, prices_close, 0, 12)
        zone_eu = calc_zone(prices_open, prices_close, 6, 18)
        zone_us = calc_zone(prices_open, prices_close, 12, 0)
        zone_asia_eth = calc_zone(prices_open_eth, prices_close_eth, 0, 12)
        zone_eu_eth = calc_zone(prices_open_eth, prices_close_eth, 6, 18)
        zone_us_eth = calc_zone(prices_open_eth, prices_close_eth, 12, 0)
        #print(zone_asia)
        #print(zone_eu)
        #print(zone_us)
        for dt in zone_asia:
            change_us = 0
            change_eu = 0
            if dt in zone_us:
                change_us = zone_us[dt]
            if dt in zone_eu:
                change_eu = zone_eu[dt]
            dbif.save_zone_change(dt, change_us, zone_asia[dt], change_eu)
            change_us_eth = 0
            change_eu_eth = 0
            if dt in zone_us_eth:
                change_us_eth = zone_us_eth[dt]
            if dt in zone_eu_eth:
                change_eu_eth = zone_eu_eth[dt]
            ethdbif.save_zone_change(dt, change_us_eth, zone_asia_eth[dt], change_eu_eth)
        while True:
            time.sleep(60)
            cur_tm = time.gmtime(time.time())
            if cur_tm.tm_hour != prev_tm.tm_hour:
                prev_tm = cur_tm
                time.sleep(60)
                prices_open, prices_close, cache_open, cache_close = get_last_price(spot_client, "BTCUSDT", cache_open, cache_close)
                prices_open_eth, prices_close_eth, cache_open_eth, cache_close_eth = get_last_price(spot_client, "ETHUSDT", cache_open_eth,
                                                                                    cache_close_eth)
                print("update", cur_tm.tm_hour)
                break

check_zone()
