"""Tools for reading content explicitly sent from the browser extension."""
from __future__ import annotations

import json
from typing import Any

from langchain_core.tools import tool

from tools._logging import _emit_input_status


def _current_thread_id() -> str:
    try:
        from persistence import get_current_agent_thread_id

        return (get_current_agent_thread_id() or "default").strip() or "default"
    except Exception:
        return "default"


def _capture_result_json(capture: dict[str, Any]) -> str:
    out = {
        "job_id": capture.get("job_id") or "",
        "url": capture.get("url") or "",
        "final_url": capture.get("final_url") or capture.get("url") or "",
        "title": capture.get("title") or "",
        "captured_at": capture.get("captured_at") or "",
        "warning": capture.get("warning") or "",
        "text_chars": capture.get("text_chars") or len(str(capture.get("text") or "")),
        "text": capture.get("text") or "",
    }
    return json.dumps(out, ensure_ascii=False)


@tool
def request_browser_page(url: str, wait_timeout_s: float = 120.0) -> str:
    """Ask the Mugi browser extension to open and capture a URL.

    Use this only after normal `read_webpage` cannot access a login-walled or
    JavaScript-heavy page. The browser extension must be installed, agent capture
    must be enabled in Mugi Settings, and the user must approve the request in
    the extension confirmation UI. The agent cannot bypass confirmation.
    """
    _emit_input_status("Requesting browser capture…")
    try:
        from browser_extension_capture import BrowserCaptureError, create_job, wait_for_job

        thread_id = _current_thread_id()
        job = create_job(url, thread_id=thread_id)
        result = wait_for_job(job["job_id"], thread_id=thread_id, timeout=min(float(wait_timeout_s or 0), 120.0))
    except Exception as exc:
        code = getattr(exc, "code", "error")
        if code == "blocked_sensitive":
            return "Browser capture was not requested: this host is sensitive and requires manual capture."
        if code == "capture_disabled":
            return "Browser capture is disabled. Ask the user to enable Agent browser capture in Mugi Settings > Network."
        if code == "busy":
            return "Browser capture is busy with another request. Try again after it completes."
        if code == "rate_limited":
            return "Browser capture request rate limit reached. Try again later."
        if code in {"punycode_host", "userinfo_not_allowed", "unsupported_scheme", "invalid_url", "url_too_long"}:
            return f"Browser capture was not requested: {code}."
        if isinstance(exc, ValueError):
            return "Browser capture was not requested: invalid timeout."
        return "Browser capture was not requested because setup or validation failed."

    if not result:
        return "Browser capture did not return a result."
    status = result.get("status")
    if status != "complete":
        job_id = result.get("job_id") or job.get("job_id") or ""
        if status == "pending" or status == "claimed":
            return f"Browser capture is still waiting for user approval or extension response (job_id={job_id})."
        reason = result.get("error") or status or "unknown"
        return f"Browser capture did not complete ({reason})."
    capture = result.get("result") or {}
    return _capture_result_json(capture)


@tool
def get_captured_browser_page(clear_after_read: bool = True, job_id: str | None = None) -> str:
    """Return the latest page text sent by the Mugi browser extension.

    Use this after read_webpage cannot access a login-walled or JavaScript-heavy
    page and the user has clicked the Mugi browser extension's "Send to Mugi"
    action on that tab. By default this consumes the single-slot capture; pass
    clear_after_read=False if you need to inspect it again in the same run.
    Pass job_id to read a specific agent-requested capture result.
    """
    _emit_input_status("Reading captured browser page…")
    from browser_extension_capture import get_capture, get_job

    jid = str(job_id or "").strip()
    if jid:
        job = get_job(jid, thread_id=_current_thread_id(), clear=bool(clear_after_read))
        if not job:
            return "No captured browser page was found for that job_id in this conversation."
        if job.get("status") != "complete":
            return f"Browser capture job is not complete yet (status={job.get('status') or 'unknown'})."
        return _capture_result_json(job.get("result") or {})

    capture = get_capture(clear=bool(clear_after_read))
    if not capture:
        return (
            "No browser page has been captured yet. Ask the user to open the page, "
            "click the Mugi browser extension's Send to Mugi action, then call "
            "get_captured_browser_page again."
        )
    return _capture_result_json(capture)
