"""
Output Contract — typed blocks for automation output_data.

Automations emit output_data with a _blocks array. Each block is a
discriminated union (TextBlock | FileBlock | FileCollectionBlock | JsonDataBlock).
The frontend switches on block.type for rendering.

This is the SDK copy for third-party developers. An identical copy lives in
apps/ai-engine-v2/orchestration/output_contract.py for first-party automations.
The canonical reference is packages/shared/src/types/output-contract.ts.
"""

from typing import Any, Literal, Union

from pydantic import BaseModel, Field, TypeAdapter

# ---------------------------------------------------------------------------
# Block models
# ---------------------------------------------------------------------------


class TextBlock(BaseModel):
    type: Literal["text"] = "text"
    label: str = Field(..., max_length=200)
    content: str
    format: Literal["markdown", "plain"] = "markdown"


class FileBlock(BaseModel):
    type: Literal["file"] = "file"
    label: str = Field(..., max_length=200)
    storage_path: str
    mime_type: str
    file_size_bytes: int | None = None


class FileCollectionBlock(BaseModel):
    type: Literal["file_collection"] = "file_collection"
    label: str = Field(..., max_length=200)
    folder_id: str | None = None


class JsonDataBlock(BaseModel):
    type: Literal["json_data"] = "json_data"
    label: str = Field(..., max_length=200)
    data: dict[str, Any] | list[Any]
    display_hint: Literal["table", "key_value", "raw"] = "key_value"


OutputBlock = Union[TextBlock, FileBlock, FileCollectionBlock, JsonDataBlock]
OutputBlockAdapter = TypeAdapter(OutputBlock)


# ---------------------------------------------------------------------------
# Builder helper
# ---------------------------------------------------------------------------


def build_output_data(
    *blocks: OutputBlock, extra: dict[str, Any] | None = None
) -> dict[str, Any]:
    """Build a valid output_data dict with typed blocks."""
    result: dict[str, Any] = {
        "_version": 1,
        "_blocks": [b.model_dump() for b in blocks],
    }
    if extra:
        result.update(extra)
    return result
