"""macOS: capture currently selected text via Cmd+C + clipboard.

Flow:
  1. Save current clipboard contents
  2. Simulate Cmd+C via CGEvent
  3. Poll pbpaste until content changes (max 0.5s)
  4. Restore original clipboard
  5. Return captured text
"""

from __future__ import annotations

import logging
import subprocess
import time

log = logging.getLogger(__name__)

_POLL_INTERVAL = 0.05
_POLL_ATTEMPTS = 10  # 0.5s total


def _pbpaste() -> str:
    """Read macOS clipboard via pbpaste."""
    try:
        result = subprocess.run(
            ["pbpaste"],
            capture_output=True,
            timeout=2,
        )
        return result.stdout.decode("utf-8", errors="replace")
    except Exception as exc:
        log.debug("pbpaste failed: %s", exc)
        return ""


def _pbcopy(text: str) -> None:
    """Write text to macOS clipboard via pbcopy."""
    try:
        subprocess.run(
            ["pbcopy"],
            input=text.encode("utf-8"),
            timeout=2,
        )
    except Exception as exc:
        log.debug("pbcopy failed: %s", exc)


def _simulate_cmd_c() -> None:
    """Simulate Cmd+C via Quartz CGEvent."""
    try:
        import Quartz  # type: ignore[import]

        CMD_KEY_CODE = 0x37  # kVK_Command
        C_KEY_CODE = 0x08  # kVK_ANSI_C
        kCGEventFlagMaskCommand = 0x100000

        src = Quartz.CGEventSourceCreate(Quartz.kCGEventSourceStateHIDSystemState)

        # Cmd down
        ev_cmd_down = Quartz.CGEventCreateKeyboardEvent(src, CMD_KEY_CODE, True)
        Quartz.CGEventPost(Quartz.kCGHIDEventTap, ev_cmd_down)
        time.sleep(0.01)

        # C down (with Cmd flag)
        ev_c_down = Quartz.CGEventCreateKeyboardEvent(src, C_KEY_CODE, True)
        Quartz.CGEventSetFlags(ev_c_down, kCGEventFlagMaskCommand)
        Quartz.CGEventPost(Quartz.kCGHIDEventTap, ev_c_down)
        time.sleep(0.01)

        # C up
        ev_c_up = Quartz.CGEventCreateKeyboardEvent(src, C_KEY_CODE, False)
        Quartz.CGEventSetFlags(ev_c_up, kCGEventFlagMaskCommand)
        Quartz.CGEventPost(Quartz.kCGHIDEventTap, ev_c_up)
        time.sleep(0.01)

        # Cmd up
        ev_cmd_up = Quartz.CGEventCreateKeyboardEvent(src, CMD_KEY_CODE, False)
        Quartz.CGEventPost(Quartz.kCGHIDEventTap, ev_cmd_up)

    except ImportError:
        # Fallback via AppleScript
        _simulate_cmd_c_applescript()
    except Exception as exc:
        log.error("CGEvent Cmd+C failed: %s", exc)
        _simulate_cmd_c_applescript()


def _simulate_cmd_c_applescript() -> None:
    """Fallback: simulate Cmd+C via AppleScript."""
    try:
        subprocess.run(
            [
                "osascript",
                "-e",
                'tell application "System Events" to keystroke "c" using command down',
            ],
            timeout=3,
        )
    except Exception as exc:
        log.error("AppleScript Cmd+C failed: %s", exc)


def get_selected_text() -> str:
    """Return currently selected text by simulating Cmd+C.

    Saves and restores the clipboard. Returns empty string on failure.
    """
    before = _pbpaste()

    _simulate_cmd_c()

    captured = ""
    for _ in range(_POLL_ATTEMPTS):
        time.sleep(_POLL_INTERVAL)
        current = _pbpaste()
        if current and current != before:
            captured = current
            break

    if captured:
        log.debug("Captured %d chars from selection", len(captured))
    else:
        log.debug("No selection captured")

    # Restore original clipboard
    if before:
        _pbcopy(before)

    return captured
