# -*- coding: utf-8 -*-
"""host/clipboard.py

Windows host PC의 텍스트 클립보드 읽기/쓰기 분리 모듈.
현재는 Tk clipboard API를 우선 사용한다. 이미 Tk 메인루프가 있는 yjm_win2rtc 구조에 가장 단순하고
추가 의존성이 없다.

주의:
- Tk clipboard 접근은 가능하면 Tk 메인 스레드에서 실행한다.
- 이미지/파일 클립보드는 아직 지원하지 않는다.
"""

from __future__ import annotations

from contextlib import contextmanager
from typing import Iterator, Optional

try:
    import tkinter as tk
except Exception:  # pragma: no cover - Windows 배포 환경 진단용
    tk = None


@contextmanager
def _temp_root() -> Iterator[object]:
    if tk is None:
        raise RuntimeError("tkinter를 사용할 수 없습니다")
    root = tk.Tk()
    root.withdraw()
    try:
        yield root
    finally:
        try:
            root.destroy()
        except Exception:
            pass


def read_text(root: Optional[object] = None, *, max_chars: int = 200_000) -> str | None:
    """텍스트 클립보드를 읽는다. 텍스트가 아니거나 비어 있으면 None일 수 있다."""
    max_chars = max(1, int(max_chars))
    if root is None:
        with _temp_root() as r:
            return read_text(r, max_chars=max_chars)
    try:
        text = root.clipboard_get()
        if not isinstance(text, str):
            text = str(text)
        return text[:max_chars]
    except Exception:
        return None


def write_text(text: object, root: Optional[object] = None, *, max_chars: int = 200_000) -> int:
    """텍스트 클립보드에 쓴다. 기록한 문자 수를 반환한다."""
    value = "" if text is None else str(text)
    value = value[: max(1, int(max_chars))]
    if root is None:
        with _temp_root() as r:
            return write_text(value, r, max_chars=max_chars)
    root.clipboard_clear()
    root.clipboard_append(value)
    # 일부 Windows/Tk 환경에서 update 없이는 외부 앱에 즉시 반영되지 않는 경우가 있다.
    try:
        root.update()
    except Exception:
        pass
    return len(value)


def preview_text(text: object, *, limit: int = 42) -> str:
    value = "" if text is None else str(text)
    value = value.replace("\r", " ").replace("\n", " ").strip()
    if len(value) > limit:
        return value[:limit] + "…"
    return value or "(빈 텍스트)"
