"""SiliconBridge tools for LangChain agents."""

from typing import Optional, Type
from pydantic import BaseModel, Field
from langchain.tools import BaseTool
import httpx


SILICONBRIDGE_BASE_URL = "https://siliconbridge.xyz"


class _SiliconBridgeBase:
    """Shared logic for all SiliconBridge tools."""

    def _submit_and_wait(self, api_key: str, service_type: str, payload: dict, timeout: int = 300) -> str:
        headers = {"X-API-Key": api_key, "Content-Type": "application/json"}
        with httpx.Client(timeout=30.0) as client:
            # Submit
            r = client.post(
                f"{SILICONBRIDGE_BASE_URL}/tasks/submit",
                headers=headers,
                json={"service_type": service_type, "payload": payload},
            )
            r.raise_for_status()
            task_id = r.json()["task_id"]

            # Poll
            import time
            deadline = time.time() + timeout
            while time.time() < deadline:
                r = client.get(f"{SILICONBRIDGE_BASE_URL}/tasks/{task_id}", headers=headers)
                r.raise_for_status()
                data = r.json()
                if data["status"] == "completed":
                    return str(data.get("result", {}).get("solution", data.get("result", "")))
                if data["status"] == "failed":
                    return f"Task failed: {data.get('result', 'unknown error')}"
                time.sleep(5)
            return f"Task {task_id} timed out after {timeout}s"


# ── CAPTCHA Solver ────────────────────────────────────────────────

class CaptchaSolveInput(BaseModel):
    image_url: str = Field(description="URL of the CAPTCHA image to solve")
    instructions: str = Field(default="Solve this CAPTCHA", description="Optional instructions for the human operator")


class SiliconBridgeCaptchaSolver(BaseTool, _SiliconBridgeBase):
    """Tool that submits a CAPTCHA to a real human operator and returns the solution."""

    name: str = "siliconbridge_captcha_solver"
    description: str = (
        "Solves CAPTCHAs by sending them to a real human operator. "
        "Use this when you encounter a CAPTCHA that blocks your progress. "
        "Input: the URL of the CAPTCHA image. Output: the solved text."
    )
    args_schema: Type[BaseModel] = CaptchaSolveInput
    api_key: str = ""

    def _run(self, image_url: str, instructions: str = "Solve this CAPTCHA") -> str:
        return self._submit_and_wait(
            self.api_key, "captcha_solve",
            {"image_url": image_url, "instructions": instructions},
        )

    async def _arun(self, image_url: str, instructions: str = "Solve this CAPTCHA") -> str:
        return self._run(image_url, instructions)


# ── Content Moderator ─────────────────────────────────────────────

class ContentModerateInput(BaseModel):
    content: str = Field(description="The content to be moderated")
    guidelines: str = Field(default="Flag hate speech, spam, or adult content", description="Moderation guidelines")


class SiliconBridgeContentModerator(BaseTool, _SiliconBridgeBase):
    """Tool that sends content to a human moderator for review."""

    name: str = "siliconbridge_content_moderator"
    description: str = (
        "Sends content to a real human moderator for review. "
        "Use when you need a human judgment call on whether content is appropriate. "
        "Input: the content text and moderation guidelines. Output: the moderation decision."
    )
    args_schema: Type[BaseModel] = ContentModerateInput
    api_key: str = ""

    def _run(self, content: str, guidelines: str = "Flag hate speech, spam, or adult content") -> str:
        return self._submit_and_wait(
            self.api_key, "content_moderate",
            {"content": content, "guidelines": guidelines},
        )

    async def _arun(self, content: str, guidelines: str = "Flag hate speech, spam, or adult content") -> str:
        return self._run(content, guidelines)


# ── Identity Verifier ─────────────────────────────────────────────

class IdentityVerifyInput(BaseModel):
    document_url: str = Field(description="URL of the identity document image")
    selfie_url: str = Field(default="", description="Optional URL of a selfie for comparison")


class SiliconBridgeIdentityVerifier(BaseTool, _SiliconBridgeBase):
    """Tool that sends identity documents to a human for verification."""

    name: str = "siliconbridge_identity_verifier"
    description: str = (
        "Sends identity documents to a real human for verification. "
        "Use when your workflow requires ID verification. "
        "Input: URL of the ID document (and optional selfie). Output: verification result."
    )
    args_schema: Type[BaseModel] = IdentityVerifyInput
    api_key: str = ""

    def _run(self, document_url: str, selfie_url: str = "") -> str:
        payload = {"document_url": document_url, "instructions": "Verify this identity document"}
        if selfie_url:
            payload["selfie_url"] = selfie_url
        return self._submit_and_wait(self.api_key, "identity_verify", payload, timeout=600)

    async def _arun(self, document_url: str, selfie_url: str = "") -> str:
        return self._run(document_url, selfie_url)


# ── Custom Task ───────────────────────────────────────────────────

class CustomTaskInput(BaseModel):
    instructions: str = Field(description="What the human operator should do")
    image_url: str = Field(default="", description="Optional image URL for context")


class SiliconBridgeCustomTask(BaseTool, _SiliconBridgeBase):
    """Tool that sends a custom task to a human operator."""

    name: str = "siliconbridge_custom_task"
    description: str = (
        "Sends any task to a real human operator. "
        "Use when you need human help with something an AI can't do: "
        "reading handwriting, verifying real-world information, making judgment calls. "
        "Input: instructions for the human. Output: their response."
    )
    args_schema: Type[BaseModel] = CustomTaskInput
    api_key: str = ""

    def _run(self, instructions: str, image_url: str = "") -> str:
        payload = {"instructions": instructions}
        if image_url:
            payload["image_url"] = image_url
        return self._submit_and_wait(self.api_key, "custom", payload)

    async def _arun(self, instructions: str, image_url: str = "") -> str:
        return self._run(instructions, image_url)


# ── Helper to get all tools ──────────────────────────────────────

def get_siliconbridge_tools(api_key: str) -> list:
    """
    Returns all SiliconBridge tools configured with your API key.

    Usage:
        from siliconbridge.integrations.langchain_tool import get_siliconbridge_tools
        tools = get_siliconbridge_tools("sb_your_key")
        agent = initialize_agent(tools=tools, ...)
    """
    return [
        SiliconBridgeCaptchaSolver(api_key=api_key),
        SiliconBridgeContentModerator(api_key=api_key),
        SiliconBridgeIdentityVerifier(api_key=api_key),
        SiliconBridgeCustomTask(api_key=api_key),
    ]
