"""
hollow.types — dataclasses for all Hollow API types.
"""

from __future__ import annotations

from dataclasses import dataclass, field
from typing import Literal, Optional

Tier = Literal["hollow", "vdom", "text", "cache", "mobile", "partial"]

ActionType = Literal["navigate", "click", "fill", "scroll", "select", "hover"]


@dataclass
class Action:
    """A single browser action to send to /api/act."""

    type: ActionType
    element_id: Optional[int] = None
    url: Optional[str] = None
    value: Optional[str] = None
    direction: Optional[Literal["up", "down"]] = None

    def to_dict(self) -> dict:
        """Serialize to camelCase dict for the Hollow API.

        Only non-None fields are included.
        """
        d: dict = {"type": self.type}
        if self.element_id is not None:
            d["elementId"] = self.element_id
        if self.url is not None:
            d["url"] = self.url
        if self.value is not None:
            d["value"] = self.value
        if self.direction is not None:
            d["direction"] = self.direction
        return d


@dataclass
class PerceiveResult:
    """Response from /api/perceive or /api/act."""

    session_id: str
    gdg_map: str
    confidence: float
    tier: Tier
    js_errors: list[str] = field(default_factory=list)


@dataclass
class AgentStep:
    """One step emitted by run_agent() via on_step."""

    step: int
    gdg_map: str
    action: Optional[Action]
    confidence: float
    tier: Tier
