"""
SiliconBridge + Playwright integration.

Works with both sync and async Playwright APIs.  Zero extra cost.

Usage (sync):
    from playwright.sync_api import sync_playwright
    from siliconbridge.integrations.playwright_bridge import PlaywrightBridge

    with sync_playwright() as p:
        browser = p.chromium.launch()
        page = browser.new_page()
        sb = PlaywrightBridge(api_key="sb_...", page=page)

        page.goto("https://example.com/login")
        code = sb.request_otp(phone="+15551234567")
        page.fill("#otp-input", code)

Usage (async):
    from siliconbridge.integrations.playwright_bridge import AsyncPlaywrightBridge

    sb = AsyncPlaywrightBridge(api_key="sb_...", page=page)
    code = await sb.request_otp(phone="+15551234567")
"""

import base64
import asyncio
from typing import Optional, Dict, Any

from siliconbridge.client import SiliconBridge


class PlaywrightBridge:
    """Sync Playwright + SiliconBridge integration."""

    def __init__(self, api_key: str, page=None, base_url: str = None, timeout: int = 300):
        self.sb = SiliconBridge(api_key=api_key, base_url=base_url)
        self.page = page
        self.timeout = timeout

    def set_page(self, page):
        self.page = page

    def screenshot_and_solve(
        self,
        instructions: str = "Solve what you see in this screenshot",
        service_type: str = "captcha",
        element=None,
        timeout: int = None,
    ) -> str:
        """Screenshot the page (or a specific element) and send to a human."""
        target = element or self.page
        png_bytes = target.screenshot()
        b64 = base64.b64encode(png_bytes).decode("utf-8")
        task = self.sb.submit_task(
            service_type,
            {"image_data": f"data:image/png;base64,{b64}", "instructions": instructions},
        )
        result = self.sb.wait_for_result(task["task_id"], timeout=timeout or self.timeout)
        return result.get("result", {}).get("solution", "")

    def request_otp(
        self,
        phone: str = None,
        email: str = None,
        instructions: str = "Enter the OTP/2FA code",
        timeout: int = None,
    ) -> str:
        payload: Dict[str, Any] = {"instructions": instructions}
        if phone:
            payload["phone"] = phone
        if email:
            payload["email"] = email
        if self.page:
            png_bytes = self.page.screenshot()
            payload["screenshot"] = base64.b64encode(png_bytes).decode("utf-8")
        task = self.sb.submit_task("otp", payload)
        result = self.sb.wait_for_result(task["task_id"], timeout=timeout or self.timeout)
        return result.get("result", {}).get("solution", "")

    def request_approval(
        self,
        action_description: str,
        context: Dict[str, Any] = None,
        timeout: int = None,
    ) -> bool:
        payload = {"instructions": action_description}
        if context:
            payload.update(context)
        if self.page:
            png_bytes = self.page.screenshot()
            payload["screenshot"] = base64.b64encode(png_bytes).decode("utf-8")
        task = self.sb.submit_task("approval", payload)
        result = self.sb.wait_for_result(task["task_id"], timeout=timeout or self.timeout)
        return result.get("result", {}).get("approved", False)

    def request_kyc_review(self, document_urls: Dict[str, str], personal_info: Dict[str, str] = None, timeout: int = None) -> Dict:
        payload = {**document_urls}
        if personal_info:
            payload["personal_info"] = personal_info
        task = self.sb.submit_task("kyc_verification", payload)
        result = self.sb.wait_for_result(task["task_id"], timeout=timeout or self.timeout)
        return result.get("result", {})

    def close(self):
        self.sb.close()

    def __enter__(self):
        return self

    def __exit__(self, *args):
        self.close()


class AsyncPlaywrightBridge:
    """Async Playwright + SiliconBridge integration."""

    def __init__(self, api_key: str, page=None, base_url: str = None, timeout: int = 300):
        self.sb = SiliconBridge(api_key=api_key, base_url=base_url)
        self.page = page
        self.timeout = timeout

    def set_page(self, page):
        self.page = page

    async def screenshot_and_solve(
        self,
        instructions: str = "Solve what you see in this screenshot",
        service_type: str = "captcha",
        element=None,
        timeout: int = None,
    ) -> str:
        target = element or self.page
        png_bytes = await target.screenshot()
        b64 = base64.b64encode(png_bytes).decode("utf-8")
        task = self.sb.submit_task(
            service_type,
            {"image_data": f"data:image/png;base64,{b64}", "instructions": instructions},
        )
        # Poll in async-friendly way
        result = await asyncio.to_thread(
            self.sb.wait_for_result, task["task_id"], timeout or self.timeout
        )
        return result.get("result", {}).get("solution", "")

    async def request_otp(
        self,
        phone: str = None,
        email: str = None,
        instructions: str = "Enter the OTP/2FA code",
        timeout: int = None,
    ) -> str:
        payload: Dict[str, Any] = {"instructions": instructions}
        if phone:
            payload["phone"] = phone
        if email:
            payload["email"] = email
        if self.page:
            png_bytes = await self.page.screenshot()
            payload["screenshot"] = base64.b64encode(png_bytes).decode("utf-8")
        task = self.sb.submit_task("otp", payload)
        result = await asyncio.to_thread(
            self.sb.wait_for_result, task["task_id"], timeout or self.timeout
        )
        return result.get("result", {}).get("solution", "")

    async def request_approval(
        self,
        action_description: str,
        context: Dict[str, Any] = None,
        timeout: int = None,
    ) -> bool:
        payload = {"instructions": action_description}
        if context:
            payload.update(context)
        if self.page:
            png_bytes = await self.page.screenshot()
            payload["screenshot"] = base64.b64encode(png_bytes).decode("utf-8")
        task = self.sb.submit_task("approval", payload)
        result = await asyncio.to_thread(
            self.sb.wait_for_result, task["task_id"], timeout or self.timeout
        )
        return result.get("result", {}).get("approved", False)

    def close(self):
        self.sb.close()

    async def __aenter__(self):
        return self

    async def __aexit__(self, *args):
        self.close()
