from __future__ import annotations

from dataclasses import dataclass, field


@dataclass
class Surface:
    ref: str
    title: str
    type: str  # "terminal" or "browser"
    selected: bool = False
    focused: bool = False
    url: str | None = None
    pane_ref: str = ""

    @property
    def is_agent(self) -> bool:
        return "claude code" in self.title.lower()


@dataclass
class Pane:
    ref: str
    focused: bool = False
    surfaces: list[Surface] = field(default_factory=list)


@dataclass
class Sidebar:
    tab_id: str = ""
    color: str = "none"
    cwd: str = ""
    focused_cwd: str = ""
    git_branch: str = "none"
    pr: str = "none"
    pr_label: str = "none"
    progress: str = "none"
    ports: str = "none"
    status_count: int = 0
    claude_code: str | None = None
    claude_color: str | None = None


@dataclass
class Workspace:
    ref: str
    title: str
    selected: bool = False
    active: bool = False
    pinned: bool = False
    panes: list[Pane] = field(default_factory=list)
    sidebar: Sidebar = field(default_factory=Sidebar)
    notifications: list[Notification] = field(default_factory=list)
    live_activity: str = ""
    _screen_has_agent: bool = False
    _screen_agent_state: str = "idle"
    _session_map_has_agent: bool = False

    @property
    def agents(self) -> list[Surface]:
        out = []
        for p in self.panes:
            for s in p.surfaces:
                if s.is_agent:
                    out.append(s)
        return out

    @property
    def has_agent(self) -> bool:
        """Check if workspace has an agent by title, sidebar, screen content, or session map."""
        return (
            bool(self.agents)
            or bool(self.sidebar.claude_code)
            or self._screen_has_agent
            or self._session_map_has_agent
        )

    _STATE_MAP = {
        "running": "running",
        "needs input": "input",
        "idle": "idle",
        "waiting": "input",
    }

    @property
    def agent_state(self) -> str:
        """Return aggregate agent state: running, input, idle, or none."""
        if not self.has_agent:
            return "none"
        sb = self.sidebar
        if sb.claude_code:
            return self._STATE_MAP.get(sb.claude_code.lower(), "running")
        # Fallback: if agents exist but no sidebar state, check progress
        if sb.progress and sb.progress != "none":
            return "running"
        # Screen-detected agent state
        if self._screen_has_agent:
            return self._screen_agent_state
        # Session-map detected but no screen info yet — assume idle
        return "idle"

    @property
    def surface_count(self) -> int:
        return sum(len(p.surfaces) for p in self.panes)


@dataclass
class Notification:
    id: str
    workspace_id: str
    surface_id: str
    is_read: bool
    title: str
    subtitle: str
    body: str
