from __future__ import annotations

import json
import sys
from typing import Any, Callable, Dict, List, Optional, Tuple, Union


def print_json(obj: Dict[str, Any]) -> None:
    text = json.dumps(obj, ensure_ascii=False) + "\n"
    buf = getattr(sys.stdout, "buffer", None)
    if buf is not None:
        buf.write(text.encode("utf-8", errors="replace"))
        buf.flush()
    else:
        print(text, end="", flush=True)


def emit_ok(data: Optional[Dict[str, Any]] = None, *, markdown: Optional[str] = None) -> None:
    body: Dict[str, Any] = {"ok": True}
    if data:
        body.update(data)
    if markdown is not None:
        body["markdown"] = markdown
    print_json(body)


def emit_need_confirm(preview: Dict[str, Any]) -> None:
    print_json({"ok": False, "error": "need_confirm", "preview": preview})


def emit_error(code: str, detail: Optional[Dict[str, Any]] = None, *, exit_code: int = 1) -> None:
    body: Dict[str, Any] = {"ok": False, "error": code}
    if detail:
        body["detail"] = detail
    print_json(body)
    if exit_code:
        sys.exit(exit_code)
