from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions outException
from selenium.webdriver import ActionChains
from selenium.webdriver.support.wait import WebDriverWait


import pandas as pd
import numpy as np
import random
import pandas as pd
from base_class import BaseVariableFunction
from base_class import *
baseclass = BaseVariableFunction(__file__)
baseclass.makedirpath(baseclass.dalao_activities_solscan_path)
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---------------")
# Python中windows路径的3种写法
# 可以是以下这样写：

# "C:\\Users\\10799\\Desktop\\learn\\C\\homework\\5"
# r"C:\Users\10799\Desktop\learn\C\homework\5"
# "C:/Users/10799/Desktop/learn/C/homework/5"
# 但是不可以这样写：
# "C:\Users\10799\Desktop\learn\C\homework\5"
with open(baseclass.code_path/"get_swapactivaties.js") as f:
    get_swapactivaties_script = f.read()

with open(baseclass.code_path/"set_utctime_solscan.js") as f:
    set_utctime_solscan_script = f.read()

with open(baseclass.code_path/"get_swapactivaties_thead_body_dom.js") as f:
    get_swapactivaties_thead_body_dom_script = f.read()

activities_columns = ['txhash', 'date', 'timestamp', 'action', 'from', 'in_tokenaddress',
                      'out_tokenaddress',
                      'in_tokenname',
                      'out_tokenname',
                      'in_tokenamount',
                      'out_tokenamount',
                      'router',
                      'israydium',
                      ]
opt = webdriver.FirefoxOptions()
# 设置无界面
opt.add_argument("--headless")
# 禁用 gpu
opt.add_argument('--disable-gpu')
# firefox_binary = "C:\\Program Files\\Mozilla Firefox\\firefox.exe"
# 指定 geckodirver 的安装路径，如果配置了环境变量则不需指定
# executable_path = "F:\\MYCode\\geckodriver\\geckodriver.exe"
# driver = webdriver.Firefox(
#     firefox_binary=firefox_binary, executable_path=executable_path, options=opt)

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

arr_str_dalaoAddress = df["dalaoAddress"].tolist()
arr_str_dalaoSwapUrl = [
    f"https://solscan.io/account/{str_dalaoAddress}#defiactivities" for str_dalaoAddress in arr_str_dalaoAddress]


print('arr_str_dalaoAddress', len(arr_str_dalaoAddress))


driver_len = 1 if len(arr_str_dalaoAddress) >= 1 else len(
    arr_str_dalaoAddress)
arr_driver = [None]*driver_len
arr_wait = [None]*driver_len
arr_home_handle = [None]*driver_len
arr_split_str_dalaoAddress = [None]*driver_len
arr_split_str_dalaoSwapUrl = [None]*driver_len
len_split_str_dalaoAddress = int(len(arr_str_dalaoAddress)/driver_len)+1
for idx_driver in range(0, driver_len):
    arr_split_str_dalaoAddress[idx_driver] = arr_str_dalaoAddress[idx_driver *
                                                                  len_split_str_dalaoAddress: (idx_driver+1)*len_split_str_dalaoAddress]
    arr_split_str_dalaoSwapUrl[idx_driver] = arr_str_dalaoSwapUrl[idx_driver *
                                                                  len_split_str_dalaoAddress: (idx_driver+1)*len_split_str_dalaoAddress]
    arr_driver[idx_driver] = webdriver.Firefox(options=opt)
    arr_wait[idx_driver] = WebDriverWait(
        arr_driver[idx_driver], 25, ignored_exceptions=None)
    arr_driver[idx_driver].get("https://solscan.io/")
    arr_driver[idx_driver].implicitly_wait(8)
    arr_home_handle[idx_driver] = arr_driver[idx_driver].current_window_handle
    print(
        f"current_window_handle={arr_driver[idx_driver].current_window_handle}")

    # driver = webdriver.Firefox(options=opt)
    # wait = WebDriverWait(driver, 25, ignored_exceptions=None)
    # driver.get("https://solscan.io/")
    # driver.implicitly_wait(8)
number_onepage = 10

# https://solscan.io/account/8T5j9shxXMYKWiLzcNYo9X11Kr3F1X83FxzjLFCUtcxV#defiactivities


driver_action = None


def get_pageselect_element(driver, wait):
    # div_select_page = wait.until(
    #     EC.visibility_of_all_elements_located(
    #         (
    #             By.CSS_SELECTOR, 'div.items-center.justify-end'
    #         )
    #     )
    # )
    # div_select_page = div_select_page[0]
    # let div_select_page = document.querySelectorAll("div.items-center.justify-end")[0];
    # let button_num_onepage = div_select_page.querySelectorAll('button[type="button"].border-input')[0];

    # button_num_onepage = wait.until(
    #     # 'button[type="button"].border-input'
    #     EC.visibility_of_all_elements_located(
    #         (
    #             By.CSS_SELECTOR, 'div.items-center.justify-end button[type="button"].border-input'
    #         )
    #     )
    # )

    while True:
        try:
            div_select_page = driver.find_element(
                By.CSS_SELECTOR, "div.items-center.justify-end")
            button_num_onepage = div_select_page.find_element(
                By.CSS_SELECTOR, 'button[type="button"].border-input')
            number_onepage = int(button_num_onepage.text.strip())

            text_page_info = driver.execute_script(
                "return arguments[0].textContent", div_select_page)
            text_page_info = text_page_info.strip()
            #  text_page_info = Show10per pagePage 1 of 2
            arr_text_page_info = text_page_info.split(' ')
            arr_text_page_info = [int(arr_text_page_info[-3]),
                                  int(arr_text_page_info[-1])]
            break
        except Exception as e:
            time.sleep(0.3)
            continue
    # div_select_page.getText().strip()

    arr_button_left_right = div_select_page.find_elements(
        By.CSS_SELECTOR,
        'button.inline-flex.items-center.justify-center.whitespace-nowrap'
    )
    button_pre_onepage = arr_button_left_right[1]
    button_aft_onepage = arr_button_left_right[2]

    return [button_num_onepage, number_onepage, arr_text_page_info, button_pre_onepage, button_aft_onepage]


set_str_dalaoAddress = set(arr_str_dalaoAddress)
split_len = 3
# while len(set_str_dalaoAddress) > 0:


def get_onedriver_activites(driver, wait, home_handle, arr_str_dalaoAddress, arr_str_dalaoSwapUrl):
    print("enter get_onedriver_activites")

    global split_len
    global set_str_dalaoAddress
    cur_set_str_dalaoAddress = set(arr_str_dalaoAddress)

    while (len(cur_set_str_dalaoAddress) > 0):

        try:
            cur_arr_str_dalaoAddress = arr_str_dalaoAddress[0:split_len]
            cur_arr_str_dalaoSwapUrl = arr_str_dalaoSwapUrl[0:split_len]

            for str_dalaoAddress_idx in range(0, len(cur_arr_str_dalaoAddress)):
                # for str_dalaoUrl in arr_str_dalaoUrl:
                str_dalaoAddress = cur_arr_str_dalaoAddress[str_dalaoAddress_idx]
                str_dalaoTransferUrl = cur_arr_str_dalaoSwapUrl[str_dalaoAddress_idx]
                script = f"window.open('{str_dalaoTransferUrl}');"
                driver.execute_script(script)
                time.sleep(random.uniform(3, 3.8))

            while (True):
                all_handles = driver.window_handles
                all_handles.remove(home_handle)

                if (len(all_handles) == 0):
                    driver.switch_to.window(
                        home_handle)
                    break
                for str_dalaoAddress_idx in range(0, len(all_handles)):
                    res_df = pd.DataFrame(columns=activities_columns)
                    driver.switch_to.window(
                        all_handles[str_dalaoAddress_idx])

                    while True:
                        notcaredata = driver.execute_script(
                            get_swapactivaties_thead_body_dom_script)

                        if notcaredata is None:
                            time.sleep(0.5)
                            continue
                        break

                    print(
                        f"enter {  driver.current_url} set_str_dalaoAddress len ={len(set_str_dalaoAddress)}")
                    str_dalaoAddress = driver.current_url.split(
                        '/')[-1].split('#')[0]

                    if (baseclass.dalao_activities_solscan_path /
                            f"solscan_act_{str_dalaoAddress}.csv").exists():
                        res_df = pd.read_csv(baseclass.dalao_activities_solscan_path /
                                             f"solscan_act_{str_dalaoAddress}.csv", dtype=object)
                    driver.execute_script(set_utctime_solscan_script)
                    time.sleep(0.5)

                    height = 0
                    while True:
                        new_height = driver.execute_script(
                            "return document.documentElement.scrollHeight;")
                        if new_height > height:
                            height = new_height
                            driver.execute_script(
                                "window.scrollTo(0,document.body.scrollHeight)")
                        else:
                            break
                        time.sleep(0.5)
                    [button_num_onepage, number_onepage, arr_text_page_info,
                     button_pre_onepage, button_aft_onepage] = get_pageselect_element(driver, wait)
                    while (number_onepage != 40):
                        driver_action = ActionChains(driver)
                        driver_action.reset_actions()
                        driver_action.move_to_element(
                            button_num_onepage).click().perform()

                        div_data_radix_select_dep1 = driver.find_element(
                            By.CSS_SELECTOR,
                            'div[data-radix-select-viewport][role="presentation"]')

                        # text = driver.execute_script(
                        #     "return arguments[0].textContent", div_data_radix_select_dep1)
                        # innerHTML = driver.execute_script(
                        #     "return arguments[0].innerHTML", div_data_radix_select_dep1)

                        arr_div_data_radix_select = div_data_radix_select_dep1.find_elements(
                            By.CSS_SELECTOR,
                            'div[role="option"]')
                        div_data_radix_select = arr_div_data_radix_select[-1]

                        driver_action.reset_actions()
                        driver_action.move_to_element(
                            div_data_radix_select).click().perform()
                        time.sleep(0.5)
                        break

                    height = 0
                    while True:
                        new_height = driver.execute_script(
                            "return document.documentElement.scrollHeight;")
                        if new_height > height:
                            height = new_height
                            driver.execute_script(
                                "window.scrollTo(0,document.body.scrollHeight)")
                        else:
                            break
                        time.sleep(0.5)

                    [button_num_onepage, number_onepage, arr_text_page_info,
                        button_pre_onepage, button_aft_onepage] = get_pageselect_element(driver, wait)

                    # number_total_txhash = arr_text_page_info[1]*40

                    number_total_page = arr_text_page_info[1] if arr_text_page_info[1] <= 13 else 13

                    for number_cur_page in range(1, number_total_page+1):
                        print(
                            f"str_dalaoAddress={str_dalaoAddress} number_cur_page={number_cur_page}")
                        while True:
                            notcaredata = driver.execute_script(
                                get_swapactivaties_thead_body_dom_script)
                            if notcaredata is None:
                                time.sleep(0.5)
                                continue
                            break

                        height = 0
                        while True:
                            new_height = driver.execute_script(
                                "return document.documentElement.scrollHeight;")
                            if new_height > height:
                                height = new_height
                                driver.execute_script(
                                    "window.scrollTo(0,document.body.scrollHeight)")
                            else:
                                break
                            time.sleep(0.5)
                        [button_num_onepage, number_onepage, arr_text_page_info,
                            button_pre_onepage, button_aft_onepage] = get_pageselect_element(driver, wait)
                        while True:
                            tbody_data = driver.execute_script(
                                get_swapactivaties_script)
                            if tbody_data is None:
                                time.sleep(0.5)
                                continue
                            elif (number_cur_page < number_total_page and len(tbody_data) != 40):
                                print("tbody_data_len=", len(tbody_data))
                                time.sleep(0.5)
                                continue
                            else:
                                break
                        page_df = pd.DataFrame(
                            tbody_data, columns=activities_columns)
                        if page_df['txhash'].tolist()[0] in res_df['txhash']:
                            # 已经存在了 不用在遍历了直接跳过
                            break

                        res_df = pd.concat([res_df, page_df],
                                           ignore_index=True).reset_index(drop=True)

                        driver_action.reset_actions()
                        driver_action.move_to_element(
                            button_aft_onepage).click().perform()
                        time.sleep(1)
                    res_df = res_df.drop_duplicates()
                    res_df.to_csv(baseclass.dalao_activities_solscan_path /
                                  f"solscan_act_{str_dalaoAddress}.csv", index=False)
                    set_str_dalaoAddress.discard(str_dalaoAddress)
                    cur_set_str_dalaoAddress.discard(str_dalaoAddress)

                    if ("defiactivities" in driver.current_url):
                        driver.close()

                    time.sleep(random.uniform(0.7, 1.1))

            arr_str_dalaoAddress = arr_str_dalaoAddress[split_len:]
            arr_str_dalaoSwapUrl = arr_str_dalaoSwapUrl[split_len:]

        except Exception as e:
            print(e)
            print(traceback.format_exc())
            continue


def get_muldriver_activities():
    thread_list = []

    for idx_driver in range(0, driver_len):
        thread = threading.Thread(
            target=get_onedriver_activites,
            args=(arr_driver[idx_driver], arr_wait[idx_driver], arr_home_handle[idx_driver], arr_split_str_dalaoAddress[idx_driver], arr_split_str_dalaoSwapUrl[idx_driver]
                  )
        )
        thread_list.append(thread)
    for thread in thread_list:
        thread.start()

    for thread in thread_list:
        thread.join()
    time.sleep(10)
    # while (True):
    #     if len(set_str_dalaoAddress) == 0:
    #         break
    #     time.sleep(1)
    for idx in range(0, driver_len):
        arr_driver[idx].close()

    return


get_muldriver_activities()

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