from datetime import timedelta
from time import sleep
import psycopg2
from pandas import DataFrame
import pandas as pd

#либы для работы с exmo
import sys
import http.client
import urllib
import json
import hashlib
import hmac
import time

PSQL_heroku_keys = access.PSQL_heroku_keys()


#текущая метка времени с минутой часами
def now_str():
    now = datetime.now()
    now_str = str(now.year) + str(
        now.month if now.month >= 10 else '0' + str(now.month)
    ) + str(now.day if now.day >= 10 else '0' + str(now.day)) + ' ' + str(
        now.hour if now.hour >= 10 else '0' + str(now.hour)) + str(
            now.minute if now.minute >= 10 else '0' +
            str(now.minute)) + str(now.second if now.second >= 10 else '0' +
                                   str(now.second))
    return now_str

def get_tv_main():

    check_at = now_str()

    PSQL_heroku_keys = access.PSQL_heroku_keys()

    interest_coins = ['ETHUSDT', 'LTCUSDT', 'EOSUSDT', 'XRPUSDT', 'DASHUSDT']

    url = 'https://scanner.tradingview.com/crypto/scan'

    strong_buy_binance = {
        "filter": [{
            "left": "name",
            "operation": "nempty"
        }, {
            "left": "exchange",
            "operation": "equal",
            "right": "BINANCE"
        }, {
            "left": "Recommend.All",
            "operation": "nequal",
            "right": 0.5
        }, {
            "left": "Recommend.All",
            "operation": "in_range",
            "right": [0.5, 1]
        }],
        "options": {
            "lang": "en"
        },
        "symbols": {
            "query": {
                "types": []
            },
            "tickers": []
        },
        "columns": [
            "name", "close", "change", "change_abs", "high", "low", "volume",
            "Recommend.All", "exchange", "description", "name", "subtype",
            "update_mode", "pricescale", "minmov", "fractional", "minmove2"
        ],
        "sort": {
            "sortBy": "name",
            "sortOrder": "asc"
        },
        "range": [0, 150]
    }

    strong_sell_binance = {
        "filter": [{
            "left": "name",
            "operation": "nempty"
        }, {
            "left": "exchange",
            "operation": "equal",
            "right": "BINANCE"
        }, {
            "left": "Recommend.All",
            "operation": "nequal",
            "right": -0.5
        }, {
            "left": "Recommend.All",
            "operation": "in_range",
            "right": [-1, -0.5]
        }],
        "options": {
            "lang": "en"
        },
        "symbols": {
            "query": {
                "types": []
            },
            "tickers": []
        },
        "columns": [
            "name", "close", "change", "change_abs", "high", "low", "volume",
            "Recommend.All", "exchange", "description", "name", "subtype",
            "update_mode", "pricescale", "minmov", "fractional", "minmove2"
        ],
        "sort": {
            "sortBy": "name",
            "sortOrder": "asc"
        },
        "range": [0, 150]
    }

    sell_binane = {
        "filter": [{
            "left": "name",
            "operation": "nempty"
        }, {
            "left": "exchange",
            "operation": "equal",
            "right": "BINANCE"
        }, {
            "left": "Recommend.All",
            "operation": "nequal",
            "right": 0
        }, {
            "left": "Recommend.All",
            "operation": "in_range",
            "right": [-0.5, 0]
        }],
        "options": {
            "lang": "en"
        },
        "symbols": {
            "query": {
                "types": []
            },
            "tickers": []
        },
        "columns": [
            "name", "close", "change", "change_abs", "high", "low", "volume",
            "Recommend.All", "exchange", "description", "name", "subtype",
            "update_mode", "pricescale", "minmov", "fractional", "minmove2"
        ],
        "sort": {
            "sortBy": "name",
            "sortOrder": "asc"
        },
        "range": [0, 150]
    }

    binance_strong_buy_str = requests.post(url, json=strong_buy_binance)
    binance_strong_sell_str = requests.post(url, json=strong_sell_binance)
    binance_sell_str = requests.post(url, json=sell_binane)

    strong_sell_dict = json.loads(binance_strong_sell_str.text)
    strong_buy_dict = json.loads(binance_strong_buy_str.text)
    sell_dict = json.loads(binance_sell_str.text)

    name_arr = []
    rating_arr = []
    prc_change_arr = []
    abs_change_arr = []
    high_change_arr = []
    low_change_arr = []

    for coin_dict in strong_sell_dict['data']:
        coin_pair = coin_dict['d'][0]
        if coin_pair in interest_coins:
            name = coin_dict['d'][0]
            prc_change = coin_dict['d'][2]
            abs_change = coin_dict['d'][3]
            high_change = coin_dict['d'][4]
            low_change = coin_dict['d'][5]

            name_arr.append(name)
            rating_arr.append('strong_sell')
            prc_change_arr.append(prc_change)
            abs_change_arr.append(abs_change)
            high_change_arr.append(high_change)
            low_change_arr.append(low_change)

    for coin_dict in strong_buy_dict['data']:
        coin_pair = coin_dict['d'][0]
        if coin_pair in interest_coins:
            name = coin_dict['d'][0]
            prc_change = coin_dict['d'][2]
            abs_change = coin_dict['d'][3]
            high_change = coin_dict['d'][4]
            low_change = coin_dict['d'][5]

            name_arr.append(name)
            rating_arr.append('strong_buy')
            prc_change_arr.append(prc_change)
            abs_change_arr.append(abs_change)
            high_change_arr.append(high_change)
            low_change_arr.append(low_change)

    for coin_dict in sell_dict['data']:
        coin_pair = coin_dict['d'][0]
        if coin_pair in interest_coins:
            name = coin_dict['d'][0]
            prc_change = coin_dict['d'][2]
            abs_change = coin_dict['d'][3]
            high_change = coin_dict['d'][4]
            low_change = coin_dict['d'][5]

            name_arr.append(name)
            rating_arr.append('sell')
            prc_change_arr.append(prc_change)
            abs_change_arr.append(abs_change)
            high_change_arr.append(high_change)
            low_change_arr.append(low_change)

    traiding_view_main_info = pd.DataFrame({
        'par_name': name_arr,
        'rating': rating_arr,
        'prc_change': prc_change_arr,
        'abs_change': abs_change_arr,
        'high_change': high_change_arr,
        'low_change': low_change_arr
    })

    if traiding_view_main_info.shape[0] > 0:

        #создаем подключение к PSQL
        conn = psycopg2.connect(
            "dbname='%(dbname)s' port='%(port)s' user='******' host='%(host)s' password='******'"
            % PSQL_heroku_keys)

        # создаем запрос
        cur = conn.cursor()

        for i, row in traiding_view_main_info.iterrows():
            insert_dict = dict(row)

            par_name = insert_dict['par_name']
            rating = insert_dict['rating']
            prc_change = insert_dict['prc_change']
            abs_change = insert_dict['abs_change']
            high_change = insert_dict['high_change']
            low_change = insert_dict['low_change']

            #создаем sql иньекцию
            sql_tv = ''.join([
                "insert into exmo_info.traiding_view_main (par_name , check_at , rating , prc_change , abs_change , high_change ,low_change) ",
                "VALUES ('", par_name, "','", check_at, "','", rating, "',",
                str(prc_change), ",",
                str(abs_change), ",",
                str(high_change), ",",
                str(low_change), ")"
            ])

            #создаем запись в exmo_info.ticker
            cur.execute(sql_tv)
            conn.commit()
            sleep(0.1)

        cur.close()
        #закрываем подключение
        conn.close()

    return 200
def main():

    check_at = now_str()

    PSQL_heroku_keys = access.PSQL_heroku_keys()

    #создаем подключение к PSQL
    conn = psycopg2.connect(
        "dbname='%(dbname)s' port='%(port)s' user='******' host='%(host)s' password='******'"
        % PSQL_heroku_keys)

    # создаем запрос
    cur = conn.cursor()

    cur_trade_state = ' '.join([
        "select mt.par_name", "\n"
        ",mt.max_check_at", "\n"
        ",round(mt_info.deal_last / mt_info.deal_24h_avg , 2) as cur_state",
        "\n"
        ",mt_info.deal_last", "\n"
        ",case when round(mt_info.deal_last / mt_info.deal_24h_avg , 3) <= 0.98 then 1 else 0 end as factor1_buy",
        "\n"
        ", case when round(mt_info.deal_last / mt_info.deal_24h_avg , 3) <= 0.98 then mt_info.deal_last * 1.015 else null end as factor1_sellprice",
        "\n"
        "from ", "\n"
        "--информация по максимальному состоянию", "\n"
        "(", "\n"
        "select par_name", "\n"
        ",max(check_at) as max_check_at", "\n"
        "from exmo_info.ticker", "\n"
        "group by par_name", "\n"
        ") as mt", "\n"
        "left join exmo_info.ticker as mt_info on mt.par_name = mt_info.par_name",
        "\n"
        "and mt.max_check_at = mt_info.check_at"
    ])

    probability_of_states = ' '.join([
        "select hy.par_name",
        "\n",
        ",hy.cur_state",
        "\n",
        ",round(sum(hy.is_price_up) / sum(1.) , 2) as cur_state_price_up_prob",
        "\n",
        ",round(sum(hy.is_factor1_up) / sum(1.) , 2) as cur_state_factor_up_prob",
        "\n",
        ",sum(1) as cnt_cases",
        "\n",
        "from(",
        "\n",
        "select p.par_name",
        "\n",
        ",round(p.deal_last / p.deal_24h_avg , 2) as cur_state",
        "\n",
        ",p.check_at",
        "\n",
        ",p.check_at + interval '2' day as end_date_order",
        "\n",
        ",p.deal_last",
        "\n",
        ",sum(case when pf.deal_last >= p.deal_last * 1.015 then 1 else 0 end) as cnt_price_up",
        "\n",
        ",sum(case when round(pf.deal_last / pf.deal_24h_avg , 3) >= round(p.deal_last / p.deal_24h_avg , 3) + 0.015 then 1 else 0 end) as cnt_factor1_up",
        "\n",
        ",max(case when pf.deal_last >= p.deal_last * 1.015 then 1 else 0 end) as is_price_up",
        "\n",
        ",max(case when round(pf.deal_last / pf.deal_24h_avg , 3) >= round(p.deal_last / p.deal_24h_avg , 3) + 0.015 then 1 else 0 end) as is_factor1_up",
        "\n",
        ",max(pf.deal_last) as max_future_deal",
        "\n",
        ",sum(1) as cnt_trys",
        "\n",
        "from exmo_info.ticker as p",
        "\n",
        "left join exmo_info.ticker as pf on p.par_name = pf.par_name",
        "\n",
        "and pf.check_at > p.check_at",
        "\n",
        "and pf.check_at < p.check_at + interval '2' day ",
        "\n",
        "where p.check_at > now() - interval '180' day",
        "\n",
        "and p.check_at < now() - interval '2' day",
        "\n",
        "group by 1 , 2 , 3 , 4 , 5",
        "\n",
        "order by p.check_at",
        "\n",
        ") as hy",
        "\n",
        "group by 1 , 2 ",
        "\n",
        "order by 1 , 2",
        "\n",
    ])

    cur.execute(cur_trade_state)
    df_cur_state = pd.DataFrame(cur.fetchall(),
                                columns=[desc[0] for desc in cur.description])

    cur.execute(probability_of_states)
    df_state_probs = pd.DataFrame(
        cur.fetchall(), columns=[desc[0] for desc in cur.description])

    cur.close()
    #закрываем подключение
    conn.close()

    #смотрим априорную вероятность увеличения стоимости в течение 2-х дней на 1.5%
    cur_state_probability = pd.merge(df_cur_state,
                                     df_state_probs,
                                     how='left',
                                     left_on=['par_name', 'cur_state'],
                                     right_on=['par_name', 'cur_state'])

    cur_state_probability.fillna('unknown', inplace=True)

    result_to_send = cur_state_probability.to_json(orient='records')

    url = 'https://fin-budg-bot.herokuapp.com/external_receive'

    try:
        r = requests.post(url, json=result_to_send)
    except:
        r = 'bad'
        print(r)

    return 200