o
    
i'                     @   s^   d Z ddlZddlZddlZddlmZmZmZmZ ddl	m
Z
 ddlmZ G dd dZdS )z
Click Element Primitive Operation

This module provides element clicking functionality with human-like mouse movement.
Uses Bezier curves and erratic movements to simulate natural human behavior.
    N)DictAnyTupleList)Page)ManagedPagec                   @   s   e Zd ZdZdd Zddedededeee	f fd	d
Z
ddededededeee	f f
ddZdedededefddZ	ddedededededeeeef  fddZdS )ClickElementa  
    Click Element with Human-like Mouse Movement

    Implements realistic mouse movement using Bezier curves with random variations
    to simulate natural human behavior. The movement includes:
    - Random starting position
    - Curved path using cubic Bezier curves
    - Random variations/jitter along the path
    - Variable speed (slower at start/end, faster in middle)

    Usage:
        clicker = ClickElement()
        result = await clicker.click_selector(managed_page, selector, slowmo=1000)
    c                 C   s   t d dS )z%Initialize the click element handler.u    🖱️ ClickElement initializedN)print)self r   @/home/byschii/byschiidev/penelope/lib/primitive/click_element.py__init__"   s   zClickElement.__init__d   managed_pageselectorslowmoreturnc              
      s  zt d| d |j|I dH }|std| d| I dH }|s.td| d| I dH }|s?td| d|d |d	 d
  t|d	  d |d	 d  }|d |d d
  t|d  d |d d  }| ||||I dH  |jj	
||I dH  ||_||_t|d I dH  d||jjd}	t d|  |	W S  ty }
 zd|t|
d}t d|
  |W  Y d}
~
S d}
~
ww )au  
        Click an element on the page with human-like mouse movement.

        Args:
            page (Page): Playwright page to use
            selector (str): CSS selector of element to click
            slowmo (int): Base delay in milliseconds for movement timing (default: 100)

        Returns:
            Dict containing click result and element information
        u   👆 Clicking element ''Nz	Element 'z' not foundz' is not visiblez(Could not get bounding box for element 'xwidth   皙?yheight  T)successr   urlu   ✅ Element clicked: F)r   r   erroru   ❌ Element click failed: )r	   pagequery_selector	Exception
is_visiblebounding_boxrandomuniform_move_mouse_human_likemouseclicklast_known_mouse_xlast_known_mouse_yasynciosleepr   str)r
   r   r   r   elementr!   boxtarget_xtarget_yresulteerror_resultr   r   r   click_selector&   sD   22zClickElement.click_selectorr   r   c              
      s   zJt d| d| d | ||||I dH  |jj||I dH  ||_||_t|d I dH  d||d|jj	d}t d	| d| d |W S  t
yq } zd
||dt|d}t d|  |W  Y d}~S d}~ww )a  
        Click at specific (x, y) position on the page with human-like mouse movement.

        Args:
            page (Page): Playwright page to use
            x (float): X coordinate to click
            y (float): Y coordinate to click
            slowmo (int): Base delay in milliseconds for movement timing (default: 100)

        Returns:
            Dict containing click result and position information
        u   👆 Clicking position (z, )Nr   T)r   r   )r   positionr   u   ✅ Position clicked: (F)r   r6   r   u   ❌ Position click failed: )r	   r%   r   r&   r'   r(   r)   r*   r+   r   r    r,   )r
   r   r   r   r   r1   r2   r3   r   r   r   click_positionf   s.   zClickElement.click_positionr/   r0   c                    s  |j }|j}|jjj||ddI dH  ttddI dH  | 	||||}t
|}t|D ]T\}	\}
}tdd}tdd}|
| }|| }|jjj||ddI dH  |	| }|dk sc|d	krp|d
 | tdd }n|d
 | tdd }t|I dH  q0dS )a  
        Move mouse from random starting position to target with human-like curved path.

        Uses cubic Bezier curves with random control points to create natural-looking
        curved movements. Adds jitter and variable speed for realism.

        Args:
            page (Page): Playwright page
            target_x (float): Target X coordinate
            target_y (float): Target Y coordinate
            slowmo (int): Base delay for timing
           )stepsNg{Gz?g?g      g      ?r   g?r   g      @      ?      ?)r(   r)   r   r&   mover*   r+   r#   r$   _generate_bezier_pathlen	enumerate)r
   r   r/   r0   r   start_xstart_ypath_pointstotal_pointsir   r   jitter_xjitter_yfinal_xfinal_yprogressdelayr   r   r   r%      s&   z#ClickElement._move_mouse_human_like   r@   rA   
num_pointsc                 C   s  t || d || d  }|| d }|| d }tdd}	||	 }
|| }|| }t ||t jd  }||d  t ||
 tdd  }||d  t ||
 tdd  }||d  t ||
 tdd	  }||d  t ||
 tdd	  }g }t|D ][}||d
  }d
| d | dd
| d  | |  dd
|  |d  |  |d |  }d
| d | dd
| d  | |  dd
|  |d  |  |d |  }|	||f q|S )a  
        Generate a curved path using cubic Bezier curve with random control points.

        Args:
            start_x (float): Starting X coordinate
            start_y (float): Starting Y coordinate
            target_x (float): Target X coordinate
            target_y (float): Target Y coordinate
            num_points (int): Number of points along the curve (default: 30)

        Returns:
            List of (x, y) tuples representing the path
        r   g333333?gffffff?gQ?r:   r;   gq=
ףp?g      g      r8      )
mathsqrtr#   r$   atan2picossinrangeappend)r
   r@   rA   r/   r0   rL   distancemid_xmid_ycurve_intensityoffsetdxdyanglecp1_xcp1_ycp2_xcp2_ypointsrD   tr   r   r   r   r   r=      sB   &&&&

z"ClickElement._generate_bezier_pathN)r   )rK   )__name__
__module____qualname____doc__r   r   r,   intr   r   r4   floatr7   r%   r   r   r=   r   r   r   r   r      s     $(@03r   )rg   r*   r#   rN   typingr   r   r   r   patchright.async_apir   lib.page_managementr   r   r   r   r   r   <module>   s   