

import json


import shutil

import urllib.parse
from base_class import BaseVariableFunction
from base_class import *

old_print = print


def timestamped_print(*args, **kwargs):
    old_print(datetime.datetime.utcnow().replace(
        microsecond=0), *args, **kwargs)


print = timestamped_print
baseclass = BaseVariableFunction(__file__)
print('\n'*5)
print(f"{'{:<6}'.format('ENTER')} {baseclass.scriptfilename} ----------------NOTE-----------NOTE---------------")
baseclass.makedirpath(baseclass.dalao_configtoken_st_solanafm_path)

Raydium_Authority_V4 = "5Q544fKrFoe6tsEbD7S8EmxGTJYAKtTVhAW5Q5pge4j1"
WSOL_Token = "So11111111111111111111111111111111111111112"


def checkgdfisswap(gdf, str_dalaoaddress):

    # 保留与raudium 有关的token 的transfer 即只参与了swap的token
    raydium_mask = ((gdf["source"] == Raydium_Authority_V4) | (
        gdf["destination"] == Raydium_Authority_V4))
    list_raydium_token = gdf[raydium_mask]["token"].drop_duplicates().tolist()
    gdf = gdf[gdf["token"].isin(list_raydium_token)]
    dalao_intoken_mask = gdf["destination"] == str_dalaoaddress
    dalao_outtoken_mask = gdf["source"] == str_dalaoaddress
    list_dalao_intoken = gdf[dalao_intoken_mask]["token"].drop_duplicates(
    ).tolist()
    list_dalao_outtoken = gdf[dalao_outtoken_mask]["token"].drop_duplicates(
    ).tolist()
    if (len(list_dalao_intoken) == 0 or len(list_dalao_outtoken) == 0):
        # dalao 没有token in 或者out 有问题 此sign 不是swap
        return None
    list_dalao_token = list(set(list_dalao_intoken) | set(list_dalao_outtoken))
    if (len(list_dalao_token) != 2):
        # dalao 的token数目不对 除了 sol token 还有其他的token 不是我想要的sign return
        return None
    if WSOL_Token not in list_dalao_token:
        # 没有sol 不是我想要的
        return None
    return gdf


def setswaptoken(gdf, str_dalaoaddress):
    dalao_intoken_mask = gdf["destination"] == str_dalaoaddress
    dalao_outtoken_mask = gdf["source"] == str_dalaoaddress
    list_dalao_intoken = gdf[dalao_intoken_mask]["token"].drop_duplicates(
    ).tolist()
    list_dalao_outtoken = gdf[dalao_outtoken_mask]["token"].drop_duplicates(
    ).tolist()
    list_dalao_token = list(set(list_dalao_intoken) | set(list_dalao_outtoken))
    list_dalao_token.remove(WSOL_Token)
    swapTokenAddress = list_dalao_token[0]
    gdf["swap_tokenaddress"] = swapTokenAddress
    return gdf


pow_ten_list = [
    '1', '10', '100', '1000',
    '10000', '100000', '1000000',
    '10000000', '100000000', '1000000000',
    '10000000000', '100000000000', '1000000000000',
    '10000000000000', '100000000000000', '1000000000000000',
    '10000000000000000', '100000000000000000', '1000000000000000000',
    '10000000000000000000', '100000000000000000000', '1000000000000000000000',
    '10000000000000000000000', '100000000000000000000000', '1000000000000000000000000'
]


# swap_ethamount	swap_tokenamount


def compute_eth_amount_onerow(row, str_dalaoaddress):
    row = row.copy()
    if (row["token"] != WSOL_Token):
        return row
    amount = decimal.Decimal(row['amount'])
    row['amount'] = '{0:.4f}'.format(
        amount / decimal.Decimal(pow_ten_list[9]))
    if (row['source'] == str_dalaoaddress):
        row['swap_eth_amount'] = '{0:.4f}'.format(decimal.Decimal(
            row['swap_eth_amount']) - decimal.Decimal(row['amount']))
    if (row['destination'] == str_dalaoaddress):
        row['swap_eth_amount'] = '{0:.4f}'.format(decimal.Decimal(
            row['swap_eth_amount']) + decimal.Decimal(row['amount']))
    return row

# def compute_eth_amount_gdf(gdf  ):
#     # 判断此hash 是buy 还是 sell
#     ,,,,
#     return

def compute_eth_amount(df, str_dalaoaddress):
    # 將主流幣全部替換為wbnb，amount 以及 token 都替換，
    # 添加swap_ethamount 列
    # 计算每条hash 的 bnb 的value
     
    df["swap_eth_amount"]="0"
    df["actiontype"]=None
    # 待添加
    # df = df.groupby(by=["sign"], group_keys=False).apply(
    # lambda gdf: compute_eth_amount_gdf(gdf))

    df = df.apply(lambda row: compute_eth_amount_onerow(
        row, str_dalaoaddress), axis=1)
    return df


def compute_token_amount_onerow(row, str_dalaoaddress):
    row = row.copy()
    if (row["token"] == WSOL_Token):
        return row
    amount = decimal.Decimal(row['amount'])
    row['amount'] = '{0:.0f}'.format(
        amount / decimal.Decimal(pow_ten_list[6]))
    if (row['source'] == str_dalaoaddress):
        row['swap_token_amount'] = '{0:.0f}'.format(decimal.Decimal(
            row['swap_token_amount']) - decimal.Decimal(row['amount']))
    if (row['destination'] == str_dalaoaddress):
        row['swap_token_amount'] = '{0:.0f}'.format(decimal.Decimal(
            row['swap_token_amount']) + decimal.Decimal(row['amount']))
    return row


def compute_token_amount(df, str_dalaoaddress):

    df = df.apply(lambda row: compute_token_amount_onerow(
        row, str_dalaoaddress), axis=1)

    return df


def get_mul_configtoken_st():
    success_address_list = arr_str_dalaoaddress.copy()
    for idx in range(0, len(arr_str_dalaoaddress), batchSize):
        thread_list = []
        for cur_idx in range(idx, min(idx+batchSize, len(arr_str_dalaoaddress))):
            thread = threading.Thread(
                target=get_one_configtoken_st,
                args=(arr_str_dalaoaddress[cur_idx],
                      success_address_list)
            )
            thread_list.append(thread)
        for thread in thread_list:
            thread.start()
        for thread in thread_list:
            thread.join()
    return


def get_one_configtoken_st(str_dalaoaddress, success_address_list):
    print(f"enter str_dalaoaddress= {str_dalaoaddress}")
    if not (baseclass.dalao_transaction_st_solanafm_path /
            f"{str_dalaoaddress}.csv").exists():
        return
    df = pd.read_csv(baseclass.dalao_transaction_st_solanafm_path /
                     f"{str_dalaoaddress}.csv", dtype=object)
    if (len(df) == 0):
        return
    df["token"] = df["token"].fillna(WSOL_Token)
    prelen = len(df)
    df = df.groupby(by=["sign"], group_keys=False).apply(
        lambda gdf: checkgdfisswap(gdf, str_dalaoaddress))

    aftlen = len(df)
    if prelen != aftlen:
        print(f"{str_dalaoaddress} pre= {prelen} aft= {aftlen}")
    if aftlen == 0:
        return

    df["swap_tokenaddress"] = ""
    df = df.groupby(by=["sign"], group_keys=False).apply(
        lambda gdf: setswaptoken(gdf, str_dalaoaddress))
    df["swap_eth_amount"] = "0"
    df = compute_eth_amount(df=df, str_dalaoaddress=str_dalaoaddress)

    df["swap_token_amount"] = "0"
    df = compute_token_amount(df=df, str_dalaoaddress=str_dalaoaddress)

    df["timestamp"] = df["timestamp"].astype(int)
    df["token_idx"] = -1
    # df["TokenFirstTime"] = df.groupby("swap_tokenaddress")[
    #     "timestamp"].transform("min")

    gettokenidx_df = df[["timestamp", "swap_tokenaddress"]].copy()
    gettokenidx_df = gettokenidx_df.sort_values(
        by=["timestamp"], ascending=[True])
    list_tokenaddress = gettokenidx_df["swap_tokenaddress"].drop_duplicates(
    ).tolist()
    for str_tokenaddress_idx in range(0, len(list_tokenaddress)):
        str_tokenaddress = list_tokenaddress[str_tokenaddress_idx]
        df.loc[df["swap_tokenaddress"] == str_tokenaddress,
               "token_idx"] = str_tokenaddress_idx+1

    df["dalaofirsttimestamp"] = df.groupby("token_idx")[
        "timestamp"].transform("min")
    df['dalaofirsttimestamp'] = pd.to_datetime(
        df['dalaofirsttimestamp'], unit='s')

    df = df.sort_values(by=["dalaofirsttimestamp", "token_idx", "timestamp"], ascending=[
        False, True, True]).reset_index(drop=True)
    df.to_csv(baseclass.dalao_configtoken_st_solanafm_path /
              f"configtoken_{str_dalaoaddress}.csv", index=False)
    success_address_list.remove(str_dalaoaddress)
    print(
        f"{str_dalaoaddress} success remainder_len={len(success_address_list)}\n", end='')


batchSize = 170
df = pd.read_csv(baseclass.dalao_merge_path /
                 "filter_dalao.csv", dtype=object)

arr_str_dalaoaddress = df["dalaoAddress"].tolist()

print('arr_str_dalaoaddress', len(arr_str_dalaoaddress))

get_mul_configtoken_st()
print(f"{'{:<6}'.format('END')} {baseclass.scriptfilename} ----------------NOTE-----------NOTE---------------")
