import time,re,json,requests,io,random
import numpy as np
from PIL import Image, ImageFilter
from scipy import ndimage
from selenium import webdriver
from selenium.webdriver.firefox.options import Options
from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains
urllib3=__import__('urllib3'); urllib3.disable_warnings()
o=Options(); o.set_preference('dom.webdriver.enabled',False)
o.set_preference('network.http.referer.spoofSource',True)
o.set_preference('network.http.referer.defaultReferrer','https://ein38eu95792b.4656hd15.cc/')
d=webdriver.Firefox(options=o); d.set_page_load_timeout(40)
try:
    d.get('http://127.0.0.1:9999/geetest_page.html')
    for _ in range(30):
        time.sleep(0.4)
        if d.execute_script("return document.querySelectorAll('.geetest_bg').length>0"): break
    time.sleep(1.5)
    info=d.execute_script("""function r(s){var e=document.querySelector(s);if(!e)return null;var b=e.getBoundingClientRect();return {t:b.top,l:b.left,w:b.width,h:b.height,bg:getComputedStyle(e).backgroundImage};}return {bg:r('.geetest_bg'),slice:r('.geetest_slice'),slicebg:r('.geetest_slice_bg'),btn:r('.geetest_btn')};""")
    def dl(u):
        m=re.search(r'url\("?([^")]+)"?\)',u or '');return requests.get(m.group(1).replace('http://','https://'),timeout=20,verify=False).content
    bg=Image.open(io.BytesIO(dl(info['bg']['bg']))).convert('RGB'); sl=Image.open(io.BytesIO(dl(info['slicebg']['bg']))).convert('RGBA')
    gra=np.array(bg).astype(np.float32); gray=gra.mean(2)
    sa=np.array(sl).astype(np.float32); mask=sa[:,:,3]>128
    contour=ndimage.binary_dilation(mask)&~ndimage.binary_erosion(mask)
    edges=np.array(bg.convert('L').filter(ImageFilter.FIND_EDGES)).astype(np.float32)
    h,w=mask.shape; H,W=gray.shape
    top=int(round((info['slice']['t']-info['bg']['t'])*H/info['bg']['h'])); top=max(0,min(H-h,top))
    scores=[]
    for x in range(0,W-w+1):
        dark=gray[top:top+h,x:x+w][mask].mean()
        edge=edges[top:top+h,x:x+w][contour].mean()
        scores.append((edge,dark,x))
    # choose max edge, tie-break min dark
    maxe=max(s[0] for s in scores)
    cand=[s for s in scores if s[0]>=maxe-1.0]
    best=min(cand,key=lambda s:s[1])
    x_nat=best[2]; scale=info['bg']['w']/W; drag=x_nat*scale
    print('chosen x',x_nat,'edge',best[0],'dark',best[1],'drag',drag,'top',top,'initdx',info['slice']['l']-info['bg']['l'])
    btn=d.find_element(By.CSS_SELECTOR,'.geetest_btn')
    ActionChains(d).move_to_element(btn).perform(); time.sleep(random.uniform(0.3,0.6))
    ActionChains(d).click_and_hold(btn).perform(); time.sleep(0.2)
    steps=32; moved=0.0
    for i in range(1,steps+1):
        t=i/steps; p=1-(1-t)**3
        target=drag*p
        dx=target-moved; moved=target
        ActionChains(d).move_by_offset(dx,0).perform()
        time.sleep(random.uniform(0.02,0.045))
    time.sleep(0.2)
    ActionChains(d).release().perform()
    time.sleep(4)
    print('validate',d.execute_script('return window.validateResult'))
    print('gtError',d.execute_script('return window.gtError'))
    print('resultText',d.execute_script("var e=document.querySelector('.geetest_result');return e?e.innerText:null"))
    print('panel',d.execute_script("var e=document.querySelector('.geetest_panel');return e?e.innerText.slice(0,200):null"))
    d.save_screenshot('gt_after.png')
finally:
    d.quit()
