"""Shared dataclasses, TypedDicts, and protocols used across team mixins."""
from __future__ import annotations

from dataclasses import dataclass
from typing import Any, Protocol, TypedDict, runtime_checkable

from logos_adk.crew import CrewProcessMode, CrewTask, CrewTaskResult, CrewTaskType
from logos_adk.crew_checkpoint_store import JSONObject
from logos_adk.types import Response


@runtime_checkable
class AgentLike(Protocol):
    """Structural protocol for objects that can participate in a Team.

    This captures the minimum interface Team requires from its agents.
    Both ``Agent`` and any duck-typed object with ``name`` and ``run()``
    satisfy this protocol (e.g. test stubs, nested Teams).
    """

    @property
    def name(self) -> str: ...

    async def run(
        self, prompt: str, *, session_id: str | None = ..., **kwargs: Any
    ) -> Response: ...


@dataclass
class _PausedCrewRun:
    run_id: str
    process: CrewProcessMode
    tasks: list[CrewTask]
    kickoff: str
    context: dict[str, str]
    task_results: list[CrewTaskResult]
    task_results_by_name: dict[str, CrewTaskResult]
    handoffs: list[dict[str, Any]]
    pending: dict[str, CrewTask]
    completed: set[str]
    pending_approval: dict[str, Any]
    max_parallel_tasks: int | None = None
    session_id: str | None = None
    kwargs: dict[str, Any] | None = None
    manager_role: str | None = None
    carried_role: str | None = None
    carried_agent: str | None = None
    last_role: str | None = None
    last_agent: str | None = None


@dataclass
class _TeamEventSubscription:
    agent_name: str
    topic: str
    handler_name: str
    target: Any
    publish_to: str | None = None


@dataclass
class CampaignState:
    """Computed campaign state derived from persisted event bus records."""

    campaign_id: str
    total_events: int
    queued_events: int
    ready_events: int
    claimed_events: int
    completed_events: int
    errored_events: int
    next_due_at: str | None = None
    last_updated_at: str | None = None


class _CrewTaskCheckpointPayload(TypedDict):
    name: str
    description: str
    task_type: CrewTaskType
    role: str | None
    agent_name: str | None
    expected_output: str | None
    depends_on: list[str]
    context: list[str]
    async_execution: bool
    approval_message: str | None
    output_key: str | None
    handoff_to_role: str | None
    handoff_to_agent: str | None
    metadata: JSONObject


class _CrewTaskResultCheckpointPayload(TypedDict):
    task_name: str
    task_type: CrewTaskType
    assigned_agent: str
    assigned_role: str | None
    prompt: str
    output: str
    status: str
    duration_ms: float
    depends_on: list[str]
    async_execution: bool
    handoff_to_role: str | None
    handoff_to_agent: str | None
    metadata: JSONObject


class _PausedCrewRunCheckpointPayload(TypedDict):
    run_id: str
    process: CrewProcessMode
    tasks: list[_CrewTaskCheckpointPayload]
    kickoff: str
    context: dict[str, str]
    task_results: list[_CrewTaskResultCheckpointPayload]
    task_results_by_name: dict[str, _CrewTaskResultCheckpointPayload]
    handoffs: list[JSONObject]
    pending: dict[str, _CrewTaskCheckpointPayload]
    completed: list[str]
    pending_approval: JSONObject
    max_parallel_tasks: int | None
    session_id: str | None
    kwargs: JSONObject
    manager_role: str | None
    carried_role: str | None
    carried_agent: str | None
    last_role: str | None
    last_agent: str | None
