
from base_class import BaseVariableFunction
from base_class import *
baseclass = BaseVariableFunction(__file__)
baseclass.makedirpath(baseclass.new_dalao_ana_fm_path)

baseclass.open_base_library()
decimal.getcontext().prec = 100
old_print = print


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


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

onedalao_ana_columns = ['TokenFirstTime', 'swap_tokenaddress',  'buy_counts', 'sell_counts',
                        'outtoken_per', 'cost_main', 'earn_main', 'earn_percent' ,'fir_cost_main','mine_earn', 'mine_fir_earn']

TotalAnalysis_columns = [
    "add",
    # "whichcontract",
    "beizhu",

    "03d_cost_noaddouttoken",
    "03d_earn_noaddouttoken",
    "03d_earnper_noaddouttoken",
    "03d_cost_dropfirsttimetx",
    "03d_earn_dropfirsttimetx",
    "03d_earnper_dropfirsttimetx",

    # "03d_difcost_noaddouttoken",
    # "03d_difearn_noaddouttoken",
    # "03d_difper_noaddouttoken",
    "03d_trans",
    "03d_mine_fir_earn_sum" ,
    "03d_mine_fir_earn_sum_dropmax",
    "03d_mine_fir_earn_sum_dropfirsttimetx",
    "03d_mine_earn_sum",
    "03d_mine_earn_sum_dropmax",
    "03d_mine_earn_sum_dropfirsttimetx",


 

    "07d_cost_noaddouttoken",
    "07d_earn_noaddouttoken",
    "07d_earnper_noaddouttoken",
    "07d_cost_dropfirsttimetx",
    "07d_earn_dropfirsttimetx",
    "07d_earnper_dropfirsttimetx",

    # "07d_difcost_noaddouttoken",
    # "07d_difearn_noaddouttoken",
    # "07d_difper_noaddouttoken",
    "07d_trans",
    "07d_mine_fir_earn_sum" ,
    "07d_mine_fir_earn_sum_dropmax",
    "07d_mine_fir_earn_sum_dropfirsttimetx",
    "07d_mine_earn_sum",
    "07d_mine_earn_sum_dropmax",
    "07d_mine_earn_sum_dropfirsttimetx",


    "11d_cost_noaddouttoken",
    "11d_earn_noaddouttoken",
    "11d_earnper_noaddouttoken",
    "11d_cost_dropfirsttimetx",
    "11d_earn_dropfirsttimetx",
    "11d_earnper_dropfirsttimetx",

    # "11d_difcost_noaddouttoken",
    # "11d_difearn_noaddouttoken",
    # "11d_difper_noaddouttoken",
    "11d_trans",
    "11d_mine_fir_earn_sum" ,
    "11d_mine_fir_earn_sum_dropmax",
    "11d_mine_fir_earn_sum_dropfirsttimetx",
    "11d_mine_earn_sum",
    "11d_mine_earn_sum_dropmax",
    "11d_mine_earn_sum_dropfirsttimetx",



    "15d_cost_noaddouttoken",
    "15d_earn_noaddouttoken",
    "15d_earnper_noaddouttoken",
    "15d_cost_dropfirsttimetx", 
    "15d_earn_dropfirsttimetx", 
    "15d_earnper_dropfirsttimetx",
    # "15d_difcost_noaddouttoken",
    # "15d_difearn_noaddouttoken",
    # "15d_difper_noaddouttoken",
    "15d_trans",
    "15d_mine_fir_earn_sum" ,
    "15d_mine_fir_earn_sum_dropmax",
    "15d_mine_fir_earn_sum_dropfirsttimetx",
    "15d_mine_earn_sum",
    "15d_mine_earn_sum_dropmax",
    "15d_mine_earn_sum_dropfirsttimetx",


    "15dearn_dif",
    "15dtxs_dif"
]


def analysis_lastdays_noaddouttoken( df, now_unix_time, intervaldays=30):
    if len(df) == 0:
        return 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
    # need consider df may null if use iloc
    lastdf = df[df["TokenFirstTime"] >=
                now_unix_time - 3600*24*intervaldays]
    # 去除那些earnper为-10的
    lastdf = lastdf[lastdf['cost_main'] != 0]
    # 去除 cost_main 过小的 <0.04  sol 理论上 同时fir_cost_main!=0
    lastdf = lastdf[lastdf['cost_main'] >= 0.04] 
    lastdf = lastdf[lastdf['fir_cost_main'] != 0]
    lastdf = lastdf.reset_index(drop=True)
    if len(lastdf) == 0:
        return 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0,0
    
    
    mine_earn_df = lastdf[["swap_tokenaddress","mine_earn","mine_fir_earn"]].drop_duplicates().reset_index(drop=True)
    last_mine_earn_sum = mine_earn_df['mine_earn'].sum()
    last_mine_earn_sum_dropmax = last_mine_earn_sum - mine_earn_df['mine_earn'].max()
    last_mine_fir_earn_sum = mine_earn_df['mine_fir_earn'].sum()
    last_mine_fir_earn_sum_dropmax = last_mine_fir_earn_sum - mine_earn_df['mine_fir_earn'].max()

    last_cost_sum = lastdf['cost_main'].sum()
    last_earn_sum = lastdf["earn_main_noaddouttoken"].sum()
    last_cost_median = lastdf['cost_main'].median()
    last_cost_mean = lastdf['cost_main'].mean()
    last_earnper = last_earn_sum / last_cost_sum if last_cost_sum != 0 else -10
    last_trans_amount = len(lastdf)
    lastdf['earn_percent'] = np.where(
        lastdf['cost_main'] != 0,
        lastdf["earn_main_noaddouttoken"] / lastdf['cost_main'],
        -10,
    )

    earnmain_max = lastdf["earn_main_noaddouttoken"].max()
    last_earn_difmax_sum = last_earn_sum - earnmain_max
    last_cost_difmax_sum = last_cost_sum - \
        lastdf[lastdf['earn_main_noaddouttoken'] == earnmain_max]['cost_main'].to_list()[
            0]
    last_dif_earnper = (
        last_earn_difmax_sum / last_cost_difmax_sum if last_cost_difmax_sum != 0 else -10
    )


    return (
        last_cost_sum,
        last_earn_sum,
        last_earnper,
        last_cost_difmax_sum,
        last_earn_difmax_sum,
        last_dif_earnper,
        last_cost_median,
        last_cost_mean,
        # last_earncount_per,
        last_trans_amount,
        # last_mine_cost_sum,
        last_mine_earn_sum,
        last_mine_earn_sum_dropmax,
        last_mine_fir_earn_sum ,
        last_mine_fir_earn_sum_dropmax,

    )


def analysis_lastdays_dropfisttimetx(df, now_unix_time, intervaldays=30):

    if len(df) == 0:
        return 0, 0, 0, 0, 0, 0,  0, 0, 0,0,0

    # need consider df may null if use iloc
    lastdf = df[df["TokenFirstTime"] >= now_unix_time - 3600*24*intervaldays]
    # 去除那些earnper为-10的
    lastdf = lastdf[lastdf['cost_main'] != 0]
    # 去除 cost_main 过小的 <0.04  sol 理论上 同时fir_cost_main!=0
    lastdf = lastdf[lastdf['cost_main'] >= 0.04] 
    lastdf = lastdf[lastdf['fir_cost_main'] != 0]
    lastdf = lastdf.reset_index(drop=True)
    if len(lastdf) == 0:
        return 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0

    mine_earn_df = lastdf[["swap_tokenaddress","mine_earn","mine_fir_earn"]].drop_duplicates().reset_index(drop=True)
    last_mine_earn_sum = mine_earn_df['mine_earn'].sum()
    last_mine_fir_earn_sum = mine_earn_df['mine_fir_earn'].sum()

    last_cost_sum = lastdf['cost_main'].sum()
    last_earn_sum = lastdf['earn_main'].sum()
    last_cost_median = lastdf['cost_main'].median()
    last_cost_mean = lastdf['cost_main'].mean()
    last_earnper = last_earn_sum / last_cost_sum if last_cost_sum != 0 else -10
    last_trans_amount = len(lastdf)
    lastdf['earn_percent'] = np.where(
        lastdf['cost_main'] != 0,
        lastdf['earn_main'] / lastdf['cost_main'],
        -10,
    )
    earnmain_max = lastdf['earn_main'].max()
    last_earn_difmax_sum = last_earn_sum - earnmain_max
    last_cost_difmax_sum = last_cost_sum - \
        lastdf[lastdf['earn_main'] == earnmain_max]['cost_main'].to_list()[0]
    last_dif_earnper = (
        last_earn_difmax_sum / last_cost_difmax_sum if last_cost_difmax_sum != 0 else -10
    )
    return (
        last_cost_sum,
        last_earn_sum,
        last_earnper,
        last_cost_difmax_sum,
        last_earn_difmax_sum,
        last_dif_earnper,
        last_cost_median,
        last_cost_mean,
        # last_earncount_per,
        last_trans_amount,
        last_mine_earn_sum,
        last_mine_fir_earn_sum

    )


def get_analyres(df,  dalao_address, now_unix_time, dropfirsttime_df):
    (last_03d_cost_noaddouttoken, last_03d_earn_noaddouttoken, last_03d_earnper_noaddouttoken, last_03d_difcost_noaddouttoken, last_03d_difearn_noaddouttoken, last_03d_difper_noaddouttoken, last_03d_costmedian_noaddouttoken, last_03d_costmean_noaddouttoken, last_03d_trans,  last_03d_mine_earn_sum , last_03d_mine_earn_sum_dropmax  , last_03d_mine_fir_earn_sum ,last_03d_mine_fir_earn_sum_dropmax ) = analysis_lastdays_noaddouttoken(
        df, now_unix_time=now_unix_time, intervaldays=3
    )
    (last_07d_cost_noaddouttoken, last_07d_earn_noaddouttoken, last_07d_earnper_noaddouttoken, last_07d_difcost_noaddouttoken, last_07d_difearn_noaddouttoken, last_07d_difper_noaddouttoken, last_07d_costmedian_noaddouttoken, last_07d_costmean_noaddouttoken, last_07d_trans, last_07d_mine_earn_sum,last_07d_mine_earn_sum_dropmax  , last_07d_mine_fir_earn_sum ,last_07d_mine_fir_earn_sum_dropmax ) = analysis_lastdays_noaddouttoken(
        df, now_unix_time=now_unix_time, intervaldays=7
    )
    (last_11d_cost_noaddouttoken, last_11d_earn_noaddouttoken, last_11d_earnper_noaddouttoken, last_11d_difcost_noaddouttoken, last_11d_difearn_noaddouttoken, last_11d_difper_noaddouttoken, last_11d_costmedian_noaddouttoken, last_11d_costmean_noaddouttoken, last_11d_trans, last_11d_mine_earn_sum,last_11d_mine_earn_sum_dropmax  , last_11d_mine_fir_earn_sum ,last_11d_mine_fir_earn_sum_dropmax ) = analysis_lastdays_noaddouttoken(
        df, now_unix_time=now_unix_time, intervaldays=11
    )
    (last_15d_cost_noaddouttoken, last_15d_earn_noaddouttoken, last_15d_earnper_noaddouttoken, last_15d_difcost_noaddouttoken, last_15d_difearn_noaddouttoken, last_15d_difper_noaddouttoken, last_15d_costmedian_noaddouttoken, last_15d_costmean_noaddouttoken, last_15d_trans, last_15d_mine_earn_sum,last_15d_mine_earn_sum_dropmax  , last_15d_mine_fir_earn_sum ,last_15d_mine_fir_earn_sum_dropmax ) = analysis_lastdays_noaddouttoken(
        df, now_unix_time=now_unix_time, intervaldays=15
    )
    (last_03d_cost_dropfirsttimetx, last_03d_earn_dropfirsttimetx, last_03d_earnper_dropfirsttimetx, last_03d_difcost_dropfirsttimetx, last_03d_difearn_dropfirsttimetx, last_03d_difper_dropfirsttimetx, last_03d_costmedian_dropfirsttimetx, last_03d_costmean_dropfirsttimetx, last_03d_trans_dropfirsttimetx ,last_03d_mine_earn_sum_dropfirsttimetx   , last_03d_mine_fir_earn_sum_dropfirsttimetx     ) = analysis_lastdays_dropfisttimetx(
        df=dropfirsttime_df, now_unix_time=now_unix_time, intervaldays=3
    )
    (last_07d_cost_dropfirsttimetx, last_07d_earn_dropfirsttimetx, last_07d_earnper_dropfirsttimetx, last_07d_difcost_dropfirsttimetx, last_07d_difearn_dropfirsttimetx, last_07d_difper_dropfirsttimetx, last_07d_costmedian_dropfirsttimetx, last_07d_costmean_dropfirsttimetx,    last_07d_trans_dropfirsttimetx ,last_07d_mine_earn_sum_dropfirsttimetx, last_07d_mine_fir_earn_sum_dropfirsttimetx  ) = analysis_lastdays_dropfisttimetx(
        df=dropfirsttime_df, now_unix_time=now_unix_time, intervaldays=7
    )
    (last_11d_cost_dropfirsttimetx, last_11d_earn_dropfirsttimetx, last_11d_earnper_dropfirsttimetx, last_11d_difcost_dropfirsttimetx, last_11d_difearn_dropfirsttimetx, last_11d_difper_dropfirsttimetx, last_11d_costmedian_dropfirsttimetx, last_11d_costmean_dropfirsttimetx, last_11d_trans_dropfirsttimetx ,last_11d_mine_earn_sum_dropfirsttimetx, last_11d_mine_fir_earn_sum_dropfirsttimetx  ) = analysis_lastdays_dropfisttimetx(
        df=dropfirsttime_df, now_unix_time=now_unix_time, intervaldays=11
    )
    (last_15d_cost_dropfirsttimetx, last_15d_earn_dropfirsttimetx, last_15d_earnper_dropfirsttimetx, last_15d_difcost_dropfirsttimetx, last_15d_difearn_dropfirsttimetx, last_15d_difper_dropfirsttimetx, last_15d_costmedian_dropfirsttimetx, last_15d_costmean_dropfirsttimetx, last_15d_trans_dropfirsttimetx ,last_15d_mine_earn_sum_dropfirsttimetx, last_15d_mine_fir_earn_sum_dropfirsttimetx  ) = analysis_lastdays_dropfisttimetx(
        df=dropfirsttime_df, now_unix_time=now_unix_time, intervaldays=15
    )
    analist = [
        dalao_address,
        "",
        last_03d_cost_noaddouttoken,
        last_03d_earn_noaddouttoken,
        last_03d_earnper_noaddouttoken,
        last_03d_cost_dropfirsttimetx, 
        last_03d_earn_dropfirsttimetx,
          last_03d_earnper_dropfirsttimetx,
        # last_03d_difcost_noaddouttoken,
        # last_03d_difearn_noaddouttoken,
        # last_03d_difper_noaddouttoken,
        last_03d_trans,
        last_03d_mine_fir_earn_sum ,
        last_03d_mine_fir_earn_sum_dropmax,
        last_03d_mine_fir_earn_sum_dropfirsttimetx,
        last_03d_mine_earn_sum,
        last_03d_mine_earn_sum_dropmax,
        last_03d_mine_earn_sum_dropfirsttimetx,


        last_07d_cost_noaddouttoken,
        last_07d_earn_noaddouttoken,
        last_07d_earnper_noaddouttoken,
        last_07d_cost_dropfirsttimetx, 
        last_07d_earn_dropfirsttimetx, 
        last_07d_earnper_dropfirsttimetx,
        # last_07d_difcost_noaddouttoken,
        # last_07d_difearn_noaddouttoken,
        # last_07d_difper_noaddouttoken,
        last_07d_trans,
        last_07d_mine_fir_earn_sum ,
        last_07d_mine_fir_earn_sum_dropmax,
        last_07d_mine_fir_earn_sum_dropfirsttimetx,
        last_07d_mine_earn_sum,
        last_07d_mine_earn_sum_dropmax,
        last_07d_mine_earn_sum_dropfirsttimetx,



        last_11d_cost_noaddouttoken,
        last_11d_earn_noaddouttoken,
        last_11d_earnper_noaddouttoken,
        last_11d_cost_dropfirsttimetx, 
        last_11d_earn_dropfirsttimetx, 
        last_11d_earnper_dropfirsttimetx,
        # last_11d_difcost_noaddouttoken,
        # last_11d_difearn_noaddouttoken,
        # last_11d_difper_noaddouttoken,
        last_11d_trans,
        last_11d_mine_fir_earn_sum ,
        last_11d_mine_fir_earn_sum_dropmax,
        last_11d_mine_fir_earn_sum_dropfirsttimetx,
        last_11d_mine_earn_sum,
        last_11d_mine_earn_sum_dropmax,
        last_11d_mine_earn_sum_dropfirsttimetx,




        last_15d_cost_noaddouttoken,
        last_15d_earn_noaddouttoken,
        last_15d_earnper_noaddouttoken,
        last_15d_cost_dropfirsttimetx,
          last_15d_earn_dropfirsttimetx, 
          last_15d_earnper_dropfirsttimetx,
        # last_15d_difcost_noaddouttoken,
        # last_15d_difearn_noaddouttoken,
        # last_15d_difper_noaddouttoken,
        last_15d_trans,
        last_15d_mine_fir_earn_sum ,
        last_15d_mine_fir_earn_sum_dropmax,
        last_15d_mine_fir_earn_sum_dropfirsttimetx,
        last_15d_mine_earn_sum,
        last_15d_mine_earn_sum_dropmax,
        last_15d_mine_earn_sum_dropfirsttimetx,


        last_15d_cost_noaddouttoken-last_15d_cost_dropfirsttimetx,
        last_15d_trans-last_15d_trans_dropfirsttimetx
    ]

    global TotalAnalysis_list
    TotalAnalysis_list.append(analist)


def calute_days(df, now_unix_time):
    df["diffdays"] = 0
    intervaldays_list = [15, 11, 7, 3]
    for intervaldays in intervaldays_list:
        df.loc[df["TokenFirstTime"] >=
               now_unix_time - 3600*24*intervaldays, "diffdays"] = intervaldays
    return df


def calucate_earnmain_dropoutoken(row):
    earnmain_amount_dropoutoken = decimal.Decimal(row['earn_main'])
    outtoken_per = decimal.Decimal(row["outtoken_per"])

    if outtoken_per >= 1.1 or outtoken_per == -10:
        earnmain_amount_dropoutoken = decimal.Decimal(0)
    earnmain_amount_dropoutoken_str = '{0:.4f}'.format(
        earnmain_amount_dropoutoken)
    return float(earnmain_amount_dropoutoken_str)


def makeDexurl(row, dalao_address):
    tokenAddress = row['swap_tokenaddress']
    urlname = f"https://dexscreener.com/solana/{tokenAddress}?maker={dalao_address}"
    return '=HYPERLINK("{}","{}")'.format(urlname, "DEX/"+tokenAddress)


def new_get_ana_df(dalao_address, df, dropfirsttime_df):
    onedalao_ana_df = df[onedalao_ana_columns].drop_duplicates(
    ).reset_index(drop=True)
    onedalao_ana_df.insert(
        loc=2, column="swap_tokenadd_dexurl", value="")
    onedalao_ana_df['swap_tokenadd_dexurl'] = onedalao_ana_df.apply(
        lambda row: makeDexurl(row, dalao_address), axis=1)
    # 如果outoken超了，earn_main_noaddouttoken 的值有两种处理方式
    # 一种设置为0 即为不亏不赚
    # 一种为全负  即为全亏了
    onedalao_ana_df["earn_main_noaddouttoken"] = onedalao_ana_df.apply(
        lambda row: calucate_earnmain_dropoutoken(row), axis=1)

    dropfirsttime_df = dropfirsttime_df[onedalao_ana_columns].drop_duplicates(
    ).reset_index(drop=True)

    get_analyres(df=onedalao_ana_df, dalao_address=dalao_address,
                 now_unix_time=now_unix_time, dropfirsttime_df=dropfirsttime_df)

    onedalao_ana_df = calute_days(
        df=onedalao_ana_df, now_unix_time=now_unix_time)
    onedalao_ana_df['TokenFirstTime'] = pd.to_datetime(
        onedalao_ana_df['TokenFirstTime'], unit='s')

    handle_onedalao_ana_df = onedalao_ana_df[onedalao_ana_df['cost_main'] != 0].reset_index(
        drop=True)

    baseclass.makedirpath(baseclass.new_dalao_ana_fm_path / dalao_address)

    onedalao_ana_df.to_csv(baseclass.new_dalao_ana_fm_path /
                           dalao_address/f"new_analysisprofit_{dalao_address}.csv", index=False)
    handle_onedalao_ana_df.to_csv(baseclass.new_dalao_ana_fm_path /
                                  dalao_address/f"new_analysisprofit_handle_{dalao_address}.csv", index=False)


def save_total_ana_df():
    global TotalAnalysis_list
    TotalAnalysis_df = pd.DataFrame(
        data=TotalAnalysis_list, columns=TotalAnalysis_columns
    )

    TotalAnalysis_df = TotalAnalysis_df.round(4)
    TotalAnalysis_df = TotalAnalysis_df.sort_values(by=["add"], ascending=[
        True]).reset_index(drop=True)

    TotalAnalysis_df.to_excel(
        baseclass.dalao_total_ana_fm_path/f"totalana_anaing_dalao.xlsx", index=False)


def get_firsttimestamp(gdf):
    gdf["TokenFirstTime"] = gdf["timestamp"].min()
    return gdf


def get_dropfirsttimestamp_df(gdf):
    gdf = gdf[gdf["dalaofirsttimestamp"] > gdf["dalaofirsttimestamp"].min()]
    return gdf


batchSize = 5
TotalAnalysis_list = []
now_unix_time = int(time.time())

# 读取 total_dalao_profit_df 转换为 totalana_anaing_dalao
df = pd.read_excel(baseclass.dalao_total_ana_fm_path /
                   f"total_dalao_profit_df.xlsx", dtype=object)

df['datetime'] = pd.to_datetime(
    df['datetime'])

df['dalaofirsttimestamp'] = pd.to_datetime(
    df['dalaofirsttimestamp'])

df = df.astype({
    'timestamp': int,
    'buy_counts': int,
    'sell_counts': int,
    'swap_eth_amount': float,
    'outtoken_per': float,
    'cost_main': float,
    'fir_cost_main':float,
    'earn_main': float,
    'earn_percent': float,
    'mine_earn':float,
    'mine_fir_earn':float,
})


# df = df[(df["outtoken_per"] <= 1.1)].reset_index(drop=True)
df = df[df['cost_main'] != 0].reset_index(drop=True)
df = df[df['fir_cost_main'] != 0].reset_index(drop=True)
 

df["TokenFirstTime"] = None
df = df.groupby(['swap_tokenaddress', 'dalaoaddress']).apply(
    lambda gdf: get_firsttimestamp(gdf)).reset_index(drop=True)


dropfirsttime_df = df.groupby(['swap_tokenaddress']).apply(
    lambda gdf: get_dropfirsttimestamp_df(gdf)).reset_index(drop=True)

dropfirsttime_df = dropfirsttime_df.sort_values(
    by=['swap_tokenaddress', 'dalaofirsttimestamp', 'dalaoaddress', 'timestamp'])


arr_str_dalao = df["dalaoaddress"].drop_duplicates().tolist()
print(f"arr_str_dalao len= {len(arr_str_dalao)}")
for str_dalao_address in arr_str_dalao:
    cur_df = df[df["dalaoaddress"] == str_dalao_address].reset_index(drop=True)
    cur_dropfirsttime_df = dropfirsttime_df[dropfirsttime_df["dalaoaddress"]
                                            == str_dalao_address].reset_index(drop=True)
    new_get_ana_df(dalao_address=str_dalao_address, df=cur_df,
                   dropfirsttime_df=cur_dropfirsttime_df)


save_total_ana_df()


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