"""Persist extraction process JSON artifacts under configured roots."""
from __future__ import annotations

import json
from datetime import date, datetime
from pathlib import Path
from typing import Any, Dict
from uuid import UUID


def _artifact_json_default(obj: Any) -> Any:
    if isinstance(obj, UUID):
        return str(obj)
    if isinstance(obj, (datetime, date)):
        return obj.isoformat()
    raise TypeError(
        f"Object of type {obj.__class__.__name__} is not JSON serializable"
    )


def resolve_under_cwd(path_str: str) -> Path:
    p = Path(path_str)
    if p.is_absolute():
        return p
    return (Path.cwd() / p).resolve()


def write_process_json(
    *,
    artifact_root: str,
    relative_segments: tuple[str, ...],
    data: Dict[str, Any],
    max_bytes: int,
) -> str:
    """
    Write UTF-8 JSON atomically. Returns POSIX-style relative path for APIs.

    Raises:
        ValueError: serialized JSON exceeds max_bytes.
    """
    root = resolve_under_cwd(artifact_root)
    rel = Path(*relative_segments)
    target = root / rel
    target.parent.mkdir(parents=True, exist_ok=True)
    raw = json.dumps(
        data,
        ensure_ascii=False,
        indent=2,
        default=_artifact_json_default,
    ).encode("utf-8")
    if len(raw) > max_bytes:
        raise ValueError(
            f"Process JSON size {len(raw)} exceeds limit {max_bytes} bytes."
        )
    tmp = target.with_suffix(target.suffix + ".tmp")
    tmp.write_bytes(raw)
    tmp.replace(target)
    return rel.as_posix()
