"""
Type definitions for Browser Bridge protocol.

These types mirror the TypeScript definitions in the browser extension.
"""

from datetime import datetime
from typing import Any, Literal, Optional

from pydantic import BaseModel, Field


class SnapshotParams(BaseModel):
    """Parameters for snapshot command."""

    interactive: bool = Field(default=True, description="Include interactive elements only")
    format: Literal["tree", "json"] = Field(default="tree", description="Output format")
    max_depth: int = Field(default=10, alias="maxDepth", description="Maximum depth to traverse")
    include_coordinates: bool = Field(
        default=False, alias="includeCoordinates", description="Include visual coordinates"
    )


class ClickParams(BaseModel):
    """Parameters for click command."""

    ref: str = Field(..., description="Element reference (e.g., @e2)")


class FillParams(BaseModel):
    """Parameters for fill command."""

    ref: str = Field(..., description="Element reference")
    text: str = Field(..., description="Text to fill")
    clear: bool = Field(default=True, description="Clear existing content first")
    submit: bool = Field(default=False, description="Submit after filling")


class NavigateParams(BaseModel):
    """Parameters for navigate command."""

    url: str = Field(..., description="URL to navigate to")
    wait_until: Literal["load", "domcontentloaded", "networkidle"] = Field(
        default="load", alias="waitUntil"
    )


class CaptureParams(BaseModel):
    """Parameters for capture command."""

    save_to_mem: bool = Field(default=False, alias="saveToMem")
    auto_extract: bool = Field(default=False, alias="autoExtract")


class InjectMemoryParams(BaseModel):
    """Parameters for inject-memory command."""

    context: str = Field(..., description="Memory context/query")
    target_ref: Optional[str] = Field(default=None, alias="targetRef")


class TabSwitchParams(BaseModel):
    """Parameters for tab switch command."""

    tab_id: int = Field(..., alias="tabId")


class BridgeCommand(BaseModel):
    """Command to send to browser bridge."""

    action: str = Field(..., description="Command action")
    params: Optional[dict[str, Any]] = Field(default=None)


class ElementRef(BaseModel):
    """Element reference in the page."""

    id: str = Field(..., description="Unique reference ID (e.g., e1, e2)")
    tag: str = Field(..., description="Element tag name")
    role: Optional[str] = None
    text: Optional[str] = None
    aria_label: Optional[str] = Field(default=None, alias="ariaLabel")
    bounds: Optional[dict[str, float]] = None
    input_type: Optional[str] = Field(default=None, alias="inputType")
    value: Optional[str] = None
    interactive: bool = True
    children: Optional[list[str]] = None


class SnapshotResult(BaseModel):
    """Snapshot result."""

    tree: str = Field(..., description="Formatted accessibility tree")
    refs: dict[str, ElementRef] = Field(..., description="Map of refs to element info")
    url: str = Field(..., description="Current page URL")
    title: str = Field(..., description="Page title")
    tab_id: int = Field(..., alias="tabId")
    timestamp: str


class ClickResult(BaseModel):
    """Click result."""

    success: bool
    ref: str
    error: Optional[str] = None


class FillResult(BaseModel):
    """Fill result."""

    success: bool
    ref: str
    error: Optional[str] = None


class NavigateResult(BaseModel):
    """Navigate result."""

    success: bool
    url: str
    title: Optional[str] = None
    error: Optional[str] = None


class CaptureResult(BaseModel):
    """Capture result."""

    success: bool
    conversation_id: Optional[str] = Field(default=None, alias="conversationId")
    message_count: Optional[int] = Field(default=None, alias="messageCount")
    saved_to_mem: Optional[bool] = Field(default=None, alias="savedToMem")
    error: Optional[str] = None


class InjectMemoryResult(BaseModel):
    """Inject memory result."""

    success: bool
    memories_found: int = Field(alias="memoriesFound")
    injected_text: Optional[str] = Field(default=None, alias="injectedText")
    error: Optional[str] = None


class StatusResult(BaseModel):
    """Status result."""

    connected: bool
    version: str
    extension_id: str = Field(alias="extensionId")
    active_tab: Optional[dict[str, Any]] = Field(default=None, alias="activeTab")


class TabInfo(BaseModel):
    """Tab info."""

    id: int
    url: str
    title: str
    active: bool
    index: int


class TabsListResult(BaseModel):
    """Tabs list result."""

    tabs: list[TabInfo]
    active_tab_id: int = Field(alias="activeTabId")


class BridgeResponse(BaseModel):
    """Generic bridge response."""

    success: bool
    data: Optional[Any] = None
    error: Optional[str] = None
    timestamp: str


class NativeMessage(BaseModel):
    """Native messaging protocol message."""

    command: BridgeCommand
    request_id: Optional[str] = Field(default=None, alias="requestId")


class NativeResponse(BaseModel):
    """Native messaging response."""

    request_id: Optional[str] = Field(default=None, alias="requestId")
    response: BridgeResponse
