#!/usr/bin/env python3
"""
Paste Text Primitive Operation

This module provides realistic clipboard paste functionality for browser automation.
Simulates human-like pasting with:
- Natural delays before/after paste
- Occasional fumbles (miss the hotkey, retry)
- Clearing existing content first
- Realistic timing variations

Use this for:
- Long text content (articles, code blocks)
- URLs and pre-formatted content
- Bulk text entry (faster than typing)

Use type_text.py for:
- Short form inputs (search queries, usernames)
- When typing animation is desired
"""

import asyncio
import random
from typing import Dict, Any, Optional
from patchright.async_api import Page


class PasteText:
    """
    Paste Text with Human-like Behavior

    Implements realistic clipboard paste that mimics human behavior:
    - Clears existing content (Ctrl+A, Backspace)
    - Natural delay before paste (hand positioning)
    - Occasional "fumbles" when pressing Ctrl+V
    - Brief verification pause after paste
    - Random timing variations

    Usage:
        paster = PasteText()
        result = await paster.paste(page, text)
    """

    def __init__(self):
        """Initialize the paste text handler."""
        print("📋 PasteText initialized")

    async def paste(
        self, 
        page: Page, 
        text: str, 
        delay_before: Optional[int] = None,
        clear_existing: bool = True
    ) -> Dict[str, Any]:
        """
        Paste text using clipboard (Ctrl+V) at the currently focused element.

        IMPORTANT: The target element should already be clicked/focused before calling this method.
        This method will clear any existing text in the focused element before pasting.

        Args:
            page (Page): Playwright page to use
            text (str): Text to paste
            delay_before (Optional[int]): Delay before pasting in ms (None = random human-like)
            clear_existing (bool): Whether to clear existing content first (default: True)

        Returns:
            Dict containing paste result and text information
        """
        try:
            print(f"📋 Pasting text: '{text[:50]}{'...' if len(text) > 50 else ''}'")

            # Clear existing text if requested
            if clear_existing:
                await self._clear_focused_element(page)

            # Calculate delay before paste (thinking/positioning)
            if delay_before is None:
                delay_before = random.uniform(100, 400)  # Human reaction time
            
            # Brief pause before paste action
            await asyncio.sleep(delay_before / 1000)

            # Occasionally "fumble" the hotkey (10% chance) - adds realism
            fumbled = False
            if random.random() < 0.10:
                fumbled = True
                print("🤷 Fumbled Ctrl+V, retrying...")
                
                # Press Ctrl but "miss" the V key timing
                await page.keyboard.down('Control')
                await asyncio.sleep(random.uniform(0.05, 0.15))  # Too long of a pause
                await page.keyboard.up('Control')
                
                # Brief pause before retry
                await asyncio.sleep(random.uniform(0.15, 0.30))

            # Perform the actual paste
            # Use page.evaluate to set clipboard then trigger paste event
            # This is more reliable than trying to set system clipboard
            await page.evaluate(f"""
                (text) => {{
                    const el = document.activeElement;
                    if (el) {{
                        // For input/textarea elements
                        if (el.tagName === 'INPUT' || el.tagName === 'TEXTAREA') {{
                            el.value = text;
                            // Trigger input event so page detects the change
                            el.dispatchEvent(new Event('input', {{ bubbles: true }}));
                            el.dispatchEvent(new Event('change', {{ bubbles: true }}));
                        }} 
                        // For contenteditable elements
                        else if (el.isContentEditable) {{
                            el.textContent = text;
                            // Trigger input event
                            el.dispatchEvent(new Event('input', {{ bubbles: true }}));
                        }}
                    }}
                }}
            """, text)

            # Brief pause after paste (human verifies it worked)
            verify_delay = random.uniform(50, 150)
            await asyncio.sleep(verify_delay / 1000)

            result = {
                "success": True,
                "text_length": len(text),
                "fumbled": fumbled,
                "delay_before_ms": delay_before,
                "url": page.url
            }

            print(f"✅ Text pasted: {len(text)} characters{' (after fumble)' if fumbled else ''}")
            return result

        except Exception as e:
            error_result = {
                "success": False,
                "error": str(e)
            }
            print(f"❌ Text pasting failed: {e}")
            return error_result

    async def _clear_focused_element(self, page: Page) -> None:
        """
        Clear any existing text in the focused element using Ctrl+A, Backspace.

        Args:
            page (Page): Playwright page to use
        """
        try:
            # Check if focused element contains text
            focused_value = await page.evaluate("""
                () => {
                    const el = document.activeElement;
                    return el && (el.value !== undefined ? el.value : el.textContent);
                }
            """)

            if focused_value and focused_value.strip():
                print(f"🗑️ Clearing existing text in focused element")
                
                # Select all with Ctrl+A
                await page.keyboard.down('Control')
                await asyncio.sleep(random.uniform(0.02, 0.04))  # Human-like key hold
                await page.keyboard.press('KeyA')
                await asyncio.sleep(random.uniform(0.01, 0.02))
                await page.keyboard.up('Control')
                await asyncio.sleep(random.uniform(0.05, 0.10))  # Brief pause after select
                
                # Delete selected text
                await page.keyboard.press('Backspace')
                await asyncio.sleep(random.uniform(0.08, 0.15))  # Pause after delete

        except Exception as e:
            print(f"⚠️ Could not check/clear focused element: {e}")
