import os, sys
import json
import time
import logging
import requests
import platform
import subprocess
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.common.action_chains import ActionChains

# Hier wird das logging erstmal auf Critical gestellt
logging.basicConfig(level=logging.CRITICAL)

# Speichere den absoluten Pfad zum Skript.
script_dir = os.path.dirname(os.path.realpath(sys.argv[0]))

# Erstelle logdatei & defeniert das format
log_file = os.path.join(script_dir, 'claim.log')
logging.basicConfig(filename=log_file,
                    format='%(asctime)s %(message)s',
                    datefmt='%d.%m.%Y %H:%M:%S',
                    filemode='w')

# Erstelle ein Aufrufbares Objekt.
logger = logging.getLogger()

# Stelle das Log Level ein
logger.setLevel(logging.INFO)

# Lade die Logindaten aus der honeygainlogin.json datei.
with open('honeygainlogin.json', 'r') as file:
    login_data = json.load(file)

username = login_data['username']
password = login_data['password']

# Nutze den vorinstallierten Chrome Browser
if platform.system() == 'Windows':
    chrome_binary = r'C:\Program Files\Google\Chrome\Application\chrome.exe' # Chrome EXE die genutzt werden soll in Windows
elif platform.system() == 'Linux':
    chrome_binary = '/usr/bin/google-chrome' # Chrome executable die genutzt werden soll in Linux

# Erstelle Chrome Argumente Variable
chrome_options = webdriver.ChromeOptions()
# Verhindert das der Chromedriver log angezeigt wird.
chrome_options.add_experimental_option('excludeSwitches', ['enable-logging'])
chrome_options.binary_location = chrome_binary
chrome_options.add_argument('--no-first-run')
chrome_options.add_argument('--no-sandbox')
# Öffnet den Chrome im Headless modus (Ohne Fenster)
chrome_options.add_argument('--headless')

# Erstelle eine Session mit Chrome und den vorher definierten Einstellungen
driver = webdriver.Chrome(options=chrome_options)

"""
Öffne Chrome mit einer Auflösung von 2560x1440

Dies ist wichtig, da sonst die info mit dem Jumpcoin über der Login-Mail eingabe hängt und daher nicht klickbar ist.
"""
driver.set_window_size(2560, 1440)

# Öffne die Loginseite
driver.get('https://dashboard.honeygain.com/login')
try:
    # Warte bis der Login Button verfügbar ist.
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.XPATH, "//button[contains(., 'Login with email')]")))
except TimeoutException:
    print("Timeout: Failed to load page within 10 seconds")
    driver.quit()

# Suche die Nutzernamen & Passwort felder und fülle diese aus.
username_field = driver.find_element(By.ID, 'email')
username_field.send_keys(username)

password_field = driver.find_element(By.ID, 'password')
password_field.send_keys(password)

# Zur Sicherheit ein 3 Sekunden Timer. Damit es nicht zu "bottig" wirkt.
time.sleep(3)

# Drücke den Login Button, scrolle gegebenfalls etwas in dessen Richtung, um sicherzustellen, dass dieser drückbar ist.
submit_button = driver.find_element(By.XPATH, "//button[contains(., 'Login with email')]")
driver.execute_script("arguments[0].scrollIntoView(true);", submit_button)
submit_button.click()
actions = ActionChains(driver)
actions.move_to_element(submit_button).click().perform()

try:
    # Warte max 10 Sekunden bis der Text "Total earnings" erscheint.
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.XPATH, "//div[contains(text(), 'Total earnings')]")))
except TimeoutException:
    print("Timeout: Failed to load page within 10 seconds")
    driver.quit()

# Lasse den Cookie Banner verschwinden.
cookie_button = driver.find_element(By.XPATH, "//button[contains(., 'Accept selected')]")
cookie_button.click()

# Zunächst überprüfen wir, ob wir schon genug Traffic zum claimen erzeugt haben
while True:
    try:
        time.sleep(5)
        traffic = driver.find_element(By.ID, "__lottie_element_2")
        traffic_element = driver.find_element(By.XPATH, "//span[contains(text(), 'MB')]")
        traffic_text = traffic_element.text
        print(f"Es wurde noch nicht genug traffic erzeugt ({traffic_text}) von 15 MB")
        print('Warte 60 Minuten und versuche es erneut')
        time.sleep(3600)
        driver.get(driver.current_url)
    except:
        # Element not found, do something else
        break

# Versuche einen Timer ausfindig zu machen
try:
    # Warte 10 Sekunden ob ein Timer auftaucht mit dem text "hours" "min" and "sec"
    timer = WebDriverWait(driver, 10).until(EC.presence_of_element_located((
        By.XPATH, "//p[contains(., 'hours') and contains(., 'min') and contains(., 'sec')]")))
    # Wenn der Timer aufgetaucht ist, finde die CSS Class und speicher diese als string.
    current_time = driver.find_element(By.CSS_SELECTOR, 'p.sc-jOiSOi.jgbyVL').text
    # Zeige eine Nachricht mit der noch zu wartenden Zeit
    print('Nächster Pot Verfügbar in:', current_time)
    # Versuche den JWT Token zu extrahieren:
    WebDriverWait(driver, 10).until(
        lambda driver: driver.execute_script('return localStorage.getItem("JWT");') is not None)

    # Definiere eine variable mit dem JWT Token inhalt.
    jwt_token = driver.execute_script('return localStorage.getItem("JWT");')

    # Nutze den JWT Token um sich für den API call anzumelden
    url = 'https://dashboard.honeygain.com/api/v1/contest_winnings'
    headers = {'Authorization': f'Bearer {jwt_token}'}
    response = requests.get(url, headers=headers)
    # Überprüfe den zurückgegebenen Status Code des API Calls
    if response.status_code == 200:
        # Extrahiere die daten aus der json und nenne die variable "winning_credits"
        winnings = response.json()['data']['winning_credits']
        # Konvertiere die Credits in $
        winnings_in_dollars = winnings / 1000
        # Nun konvertieren wir die Credits in integer und dann zurück in einen String, dadurch streichen wir nachkommastellen (5 Credits werden als 5.0 angegeben, aber es gibt keine 0.5 Credits)
        winnings_int = int(winnings)
        winnings_str = str(winnings_int)
        # Zeige eine Nachricht mit den Credits die heute gewonnen wurden.
        print('Du hast heute', winnings_str ,'Credits (', winnings_in_dollars, '$) gewonnen.')
    else:
        print('Error:', response.status_code, response.text)
except TimeoutException:
    # Falls der Timer nicht vorhanden ist, schaue ob der Lucky Port geclaimed werden kann
    try:
        # Warte max 10 Sekunden bis der text "Open Lucky Pot" auf der Seite erscheint.
        WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.XPATH, "//span[contains(text(), 'Open Lucky Pot')]")))
        # Klicke den Lucky Pot button:
        lucky_pot_button = driver.find_element(By.XPATH, "//span[contains(text(), 'Open Lucky Pot')]/ancestor::button")
        lucky_pot_button.click()
        # Definiere eine variable mit dem JWT Token inhalt.
        jwt_token = driver.execute_script('return localStorage.getItem("JWT");')
    
        # Nutze den JWT Token um sich für den API call anzumelden
        url = 'https://dashboard.honeygain.com/api/v1/contest_winnings'
        headers = {'Authorization': f'Bearer {jwt_token}'}
        response = requests.get(url, headers=headers)
        # Überprüfe den zurückgegebenen Status Code des API Calls
        if response.status_code == 200:
            # Extrahiere die daten aus der json und nenne die variable "winning_credits"
            winnings = response.json()['data']['winning_credits']
            # Konvertiere die Credits in $
            winnings_in_dollars = winnings / 1000
            # Nun konvertieren wir die Credits in integer und dann zurück in einen String, dadurch streichen wir nachkommastellen (5 Credits werden als 5.0 angegeben, aber es gibt keine 0.5 Credits)
            winnings_int = int(winnings)
            winnings_str = str(winnings_int)
            # Zeige eine Nachricht mit den Credits die heute gewonnen wurden.
            print('Der LuckyPot wurde erfolgreich geclaimed! Du hast', winnings_str ,'Credits (', winnings_in_dollars, '$) gewonnen.')

    except TimeoutException:
        print("The 'Open Lucky Pot' button was not found within 10 seconds. Exiting...")

driver.quit()