"""LangGraph workflow state schema.

Defines the TypedDict that flows through every node in the StateGraph.
Field names align with OrchestratorConfig (src/workflows/orchestrator.py:28-78)
so existing phase logic can be reused without translation.
"""

from __future__ import annotations

import uuid
from datetime import datetime
from typing import Any, Dict, List, Optional, TypedDict


class PhaseResultDict(TypedDict, total=False):
    """Result of a single phase execution."""
    name: str
    status: str             # pending | running | completed | skipped | error
    started_at: Optional[str]
    ended_at: Optional[str]
    duration_seconds: float
    output: Dict[str, Any]
    error: Optional[str]


class AgentMessageDict(TypedDict, total=False):
    """Serialisable representation of an inter-agent message."""
    id: str
    sender: str
    recipient: str
    content: str
    message_type: str       # request | response | error | human_gate
    metadata: Dict[str, Any]
    timestamp: str


class WorkflowState(TypedDict, total=False):
    """Shared state passed between all LangGraph nodes.

    Uses TypedDict so LangGraph can type-check channels.
    All fields are optional (total=False) because nodes progressively
    populate them.
    """

    # --- Identity ---
    run_id: str
    started_at: str

    # --- Configuration (mirrors OrchestratorConfig fields) ---
    config: Dict[str, Any]

    # --- Phase tracking ---
    current_phase: str
    phase_results: Dict[str, PhaseResultDict]
    completed_phases: List[str]

    # --- Inter-agent messages ---
    messages: List[AgentMessageDict]

    # --- Error tracking ---
    errors: List[Dict[str, Any]]

    # --- Human-in-the-loop ---
    human_approval_needed: bool
    human_approval_phase: str
    human_response: Optional[str]

    # --- Accumulated context (phase outputs keyed by phase name) ---
    context: Dict[str, Any]

    # --- Arbitrary metadata ---
    metadata: Dict[str, Any]

    # --- Final status ---
    status: str             # pending | running | completed | partial | failed


def create_initial_state(config: Dict[str, Any]) -> WorkflowState:
    """Create a fresh WorkflowState with sensible defaults.

    Args:
        config: Orchestrator configuration dict (same fields as OrchestratorConfig).

    Returns:
        Initialised WorkflowState ready for graph execution.
    """
    return WorkflowState(
        run_id=f"lg_run_{uuid.uuid4().hex[:8]}",
        started_at=datetime.utcnow().isoformat() + "Z",
        config=config,
        current_phase="",
        phase_results={},
        completed_phases=[],
        messages=[],
        errors=[],
        human_approval_needed=False,
        human_approval_phase="",
        human_response=None,
        context={},
        metadata={},
        status="pending",
    )
