"""Screen capture — works under macOS TCC and on Windows.

macOS: Jarvis used to shell out `screencapture` via the Bash tool, but that
runs deep inside the bundled `claude` CLI process tree, which macOS holds
responsible for the TCC check — NOT Jarvis.app — so capture was denied no
matter how many times Ahmed toggled the app on. The engine process (this
Python) is a direct child of Jarvis.app (the app that holds the grant), so we
capture HERE and the `screencapture` we spawn inherits the engine's
responsible process. CoreGraphics' CGDisplayCreateImage is deprecated on
macOS 26 (Tahoe) and returns a BLANK image — `screencapture` still works.

Windows: no screen-recording permission wall (no TCC), so `mss` (fast
multi-monitor grabber) writes the PNG directly; nothing to preflight.

Public interface is identical on both so main.py / control.py call it
unchanged: has_access(), request_access(), capture(path, display).
"""

from __future__ import annotations

import os
import sys

_DARWIN = sys.platform == "darwin"


# ---------------------------------------------------------------------------
# macOS (screencapture CLI, run in the engine = attributed to Jarvis.app)
# ---------------------------------------------------------------------------
def _mac_has_access() -> bool:
    import Quartz
    return bool(Quartz.CGPreflightScreenCaptureAccess())


def _mac_request_access() -> bool:
    import Quartz
    return bool(Quartz.CGRequestScreenCaptureAccess())


def _mac_capture(path: str, display=None) -> tuple[bool, str | None]:
    if not _mac_has_access():
        _mac_request_access()  # registers Jarvis.app + prompts Ahmed once
        if not _mac_has_access():
            return False, "no_screen_recording_permission"
    parent = os.path.dirname(path)
    if parent:
        os.makedirs(parent, exist_ok=True)
    args = ["screencapture", "-x"]
    if display is not None:
        try:
            args += ["-D", str(int(display))]
        except (TypeError, ValueError):
            pass
    args.append(path)
    import subprocess
    try:
        r = subprocess.run(args, capture_output=True, text=True, timeout=15)
    except Exception as e:  # noqa: BLE001
        return False, f"capture_error:{e}"[:120]
    if r.returncode != 0:
        return False, (r.stderr.strip() or "screencapture_failed")[:120]
    return True, None


# ---------------------------------------------------------------------------
# Windows / other (mss — no permission wall)
# ---------------------------------------------------------------------------
def _mss_capture(path: str, display=None) -> tuple[bool, str | None]:
    try:
        import mss
        import mss.tools

        parent = os.path.dirname(path)
        if parent:
            os.makedirs(parent, exist_ok=True)
        with mss.mss() as sct:
            monitors = sct.monitors
            if not display:
                mon = monitors[1] if len(monitors) > 1 else monitors[0]
            else:
                n = int(display)
                mon = monitors[n] if 0 <= n < len(monitors) else (
                    monitors[1] if len(monitors) > 1 else monitors[0])
            img = sct.grab(mon)
            mss.tools.to_png(img.rgb, img.size, output=path)
        return True, None
    except Exception as e:  # noqa: BLE001
        return False, f"capture_error:{e}"[:120]


# ---------------------------------------------------------------------------
# platform dispatch
# ---------------------------------------------------------------------------
def has_access() -> bool:
    """True if this process may record the screen. Windows: always."""
    if _DARWIN:
        try:
            return _mac_has_access()
        except Exception:  # noqa: BLE001 — Quartz missing shouldn't crash
            return False
    return True


def request_access() -> bool:
    """Prompt for Screen Recording (macOS) / no-op (Windows). Returns whether
    access is granted right now — a fresh macOS grant may only apply after the
    app is relaunched."""
    if _DARWIN:
        try:
            return _mac_request_access()
        except Exception:  # noqa: BLE001
            return False
    return True


def capture(path: str, display=None) -> tuple[bool, str | None]:
    """Capture a display to `path` as PNG. `display` is 1-based (None = main).
    Returns (ok, error_slug)."""
    return _mac_capture(path, display) if _DARWIN else _mss_capture(path, display)
