"""Common result and error types for PUREFN operations.

Provides standardized JSON envelopes for success/failure responses.
"""

from __future__ import annotations

from dataclasses import dataclass, field
from typing import Any


@dataclass(frozen=True)
class PureResult:
    """Standard result envelope for all PUREFN operations.

    Attributes:
        ok: Whether the operation succeeded.
        global_token: New public game state token (empty string on error).
        views: Human/agent-friendly views of state.
        private: Private outputs (e.g., player hashes, secrets).
        events: Normalized events produced by this operation.
        commit: SHA256 fingerprint of the token for integrity.
        error: Error message (only present when ok=False).
    """

    ok: bool
    global_token: str = ""
    views: dict[str, Any] = field(default_factory=dict)
    private: dict[str, Any] = field(default_factory=dict)
    events: list[dict[str, Any]] = field(default_factory=list)
    commit: str = ""
    error: str | None = None

    def to_dict(self) -> dict[str, Any]:
        """Convert to dictionary for JSON serialization.

        Omits None/empty fields for cleaner output.

        Returns:
            Dictionary representation
        """
        result: dict[str, Any] = {"ok": self.ok}

        if self.global_token:
            result["global"] = self.global_token
        if self.views:
            result["views"] = self.views
        if self.private:
            result["private"] = self.private
        if self.events:
            result["events"] = self.events
        if self.commit:
            result["commit"] = self.commit
        if self.error:
            result["error"] = self.error

        return result


def success(
    global_token: str,
    commit: str,
    views: dict[str, Any] | None = None,
    private: dict[str, Any] | None = None,
    events: list[dict[str, Any]] | None = None,
) -> PureResult:
    """Create a success result.

    Args:
        global_token: New global state token
        commit: Token commitment hash
        views: State views (optional)
        private: Private outputs like player hashes (optional)
        events: Event list produced by operation (optional)

    Returns:
        Success result
    """
    return PureResult(
        ok=True,
        global_token=global_token,
        views=views or {},
        private=private or {},
        events=events or [],
        commit=commit,
    )


def error(message: str) -> PureResult:
    """Create an error result.

    Args:
        message: Error description

    Returns:
        Error result
    """
    return PureResult(ok=False, error=message)
