from typing import Callable
import pynput.keyboard as keyboard
import pynput.mouse as mouse
from secrets import randbelow
from pynput.mouse import Button
from pynput.keyboard import Key
import time

# Constants
key_quick_prayers = 'o'
key_book_activation = 'p'
key_pvm_hub_teleport = 'h'
key_aggression_portion = '7'
key_lantadyme_stick = '8'

position_compass = (1173 , 34)
position_bank_chest_teleport = (896, 238)
position_bank_chest_after = (676, 339)
position_ectoplasm = (1210, 478)
position_ectoplasmator = (1210, 447)
position_open_page = (1250, 443)
position_select_all_page = (1205, 484)
position_open_springs = (1290, 444)
position_select_all_springs = (1256, 485)
position_open_divine_charge = (1330, 444)
position_select_all_divine_charge = (1267, 518)

k = keyboard.Controller()
m = mouse.Controller()

def random_between(minimum: int, maximum: int) -> int:
    delta = maximum - minimum
    return minimum + randbelow(delta)

def random_sleep_between(min_milliseconds: int, max_milliseconds: int) -> int:
    sleep_microseconds = random_between(min_milliseconds * 1_000, max_milliseconds * 1_000)
    sleep_seconds = sleep_microseconds / 1_000_000
    print(f"Sleeping for: {sleep_seconds} seconds")
    time.sleep(sleep_seconds)
    return sleep_microseconds

def click_at(position: tuple[int,int]):
    m.position = position
    m.click(Button.left)

def right_click_at(position: tuple[int,int]):
    m.position = position
    m.click(Button.right)

def full_setup():
    k.tap(key_pvm_hub_teleport)
    random_sleep_between(6_000, 7_000)
    click_at(position_compass)
    random_sleep_between(100, 300)
    click_at(position_bank_chest_teleport)
    random_sleep_between(4_000, 5_000)
    k.tap('2')
    random_sleep_between(1_800, 2_200)
    click_at(position_ectoplasm)
    random_sleep_between(500, 700)
    click_at(position_ectoplasmator)
    random_sleep_between(1_200, 1_400)
    k.type('999')
    random_sleep_between(500, 700)
    k.tap(Key.enter)
    random_sleep_between(500, 700)
    right_click_at(position_open_page)
    random_sleep_between(500, 700)
    click_at(position_select_all_page)
    random_sleep_between(500, 700)
    right_click_at(position_open_springs)
    random_sleep_between(500, 700)
    click_at(position_select_all_springs)
    random_sleep_between(500, 700)
    right_click_at(position_open_divine_charge)
    random_sleep_between(500, 700)
    click_at(position_select_all_divine_charge)
    random_sleep_between(500, 700)
    click_at(position_bank_chest_after)
    random_sleep_between(1_800, 2_200)
    k.tap('1')

def add_keybind(keybind: str | Key, action: Callable):
    def on_release(key):
        try:
            if key == keybind:
                action()
            else:
                if key.char == keybind:
                    action()
        except:
            pass
    
    keyboard.Listener(on_release=on_release).start()

add_keybind(Key.f12, full_setup)
    
while True:
    time.sleep(1000)