"""
Handoff MCP Tools
==================
Structured auto-handoff when an agent finishes a block of work.
Enables seamless context transfer between Claude and Antigravity agents.

Tools:
- handoff_push: Write structured handoff + publish event
- handoff_pull: Read latest handoff(s) + recent events since last sync
"""

import json
import sys
import logging
from datetime import datetime
from pathlib import Path

logger = logging.getLogger(__name__)

# Paths
SYNC_DIR = Path("/mnt/e/genesis-system/data/antigravity-sync")
HANDOFFS_DIR = SYNC_DIR / "handoffs"
EVENTS_FILE = SYNC_DIR / "events.jsonl"
STATE_FILE = SYNC_DIR / "current_state.json"

# Lazy AgentBus
_agent_bus = None


def _get_agent_bus():
    """Lazy load AgentBus."""
    global _agent_bus
    if _agent_bus is None:
        try:
            sys.path.insert(0, '/mnt/e/genesis-system')
            sys.path.insert(0, '/mnt/e/genesis-system/data/genesis-memory')
            from AIVA.agents.agent_bus import AgentBus
            from AIVA.agents.message_schemas import AgentType
            _agent_bus = AgentBus(agent_type=AgentType.CLAUDE, enable_audit=False)
            _agent_bus.connect()
        except Exception as e:
            logger.warning(f"AgentBus unavailable for handoffs: {e}")
    return _agent_bus


def _log_event(source: str, event_type: str, data: dict):
    """Append event to events.jsonl."""
    try:
        event = {
            "timestamp": datetime.utcnow().isoformat(),
            "source": source,
            "type": event_type,
            "data": data
        }
        EVENTS_FILE.parent.mkdir(parents=True, exist_ok=True)
        with open(EVENTS_FILE, "a") as f:
            f.write(json.dumps(event) + "\n")
    except Exception as e:
        logger.error(f"Failed to log event: {e}")


def _update_current_state(agent: str, handoff_summary: str):
    """Update current_state.json with latest handoff info."""
    try:
        state = {}
        if STATE_FILE.exists():
            with open(STATE_FILE, "r") as f:
                state = json.load(f)

        state["last_updated"] = datetime.utcnow().isoformat()
        if "coordination" not in state:
            state["coordination"] = {}

        state["coordination"]["last_handoff"] = {
            "agent": agent,
            "summary": handoff_summary[:500],
            "timestamp": datetime.utcnow().isoformat()
        }

        with open(STATE_FILE, "w") as f:
            json.dump(state, f, indent=2)
    except Exception as e:
        logger.error(f"Failed to update current state: {e}")


def handoff_push(summary: str, files_changed_json: str, next_actions_json: str) -> str:
    """
    Push a structured handoff when an agent finishes a block of work.

    Args:
        summary: What was done (text description)
        files_changed_json: JSON array of file paths that were changed
        next_actions_json: JSON array of recommended next actions

    Returns:
        JSON with handoff ID and status
    """
    try:
        files_changed = json.loads(files_changed_json) if files_changed_json else []
    except json.JSONDecodeError:
        files_changed = []

    try:
        next_actions = json.loads(next_actions_json) if next_actions_json else []
    except json.JSONDecodeError:
        next_actions = []

    agent = "claude"  # This tool is called from Claude's context
    now = datetime.utcnow().isoformat()

    handoff = {
        "agent": agent,
        "timestamp": now,
        "summary": summary,
        "files_changed": files_changed,
        "tasks_completed": [],
        "tasks_created": [],
        "next_actions": next_actions,
        "context_snapshot": {
            "session_id": None,
            "token_usage": None
        }
    }

    # 1. Write to handoff file
    HANDOFFS_DIR.mkdir(parents=True, exist_ok=True)
    latest_file = HANDOFFS_DIR / f"LATEST_{agent}.json"
    archive_file = HANDOFFS_DIR / f"{agent}_{now.replace(':', '-')}.json"

    try:
        with open(latest_file, "w") as f:
            json.dump(handoff, f, indent=2)
        with open(archive_file, "w") as f:
            json.dump(handoff, f, indent=2)
    except Exception as e:
        logger.error(f"Failed to write handoff file: {e}")

    # 2. Publish Redis event
    bus = _get_agent_bus()
    if bus:
        try:
            from AIVA.agents.message_schemas import EventMessage, AgentType
            msg = EventMessage(
                sender=AgentType.CLAUDE,
                channel="aiva:events",
                event_type="handoff_pushed",
                payload={
                    "agent": agent,
                    "summary": summary[:200],
                    "files_count": len(files_changed),
                    "actions_count": len(next_actions)
                },
                severity="info"
            )
            bus.publish("aiva:events", msg)
        except Exception as e:
            logger.debug(f"Redis handoff event failed: {e}")

    # 3. Update current_state.json
    _update_current_state(agent, summary)

    # 4. Log event
    _log_event(agent, "handoff_pushed", {
        "summary": summary[:200],
        "files_changed": len(files_changed),
        "next_actions": len(next_actions)
    })

    return json.dumps({
        "handoff_id": f"{agent}_{now}",
        "status": "pushed",
        "file": str(latest_file),
        "files_changed": len(files_changed),
        "next_actions": len(next_actions)
    })


def handoff_pull(agent: str = "") -> str:
    """
    Pull latest handoff(s) and recent events since last sync.

    Args:
        agent: Filter by agent name (empty = all agents). Common values:
               "claude", "antigravity"

    Returns:
        JSON with latest handoffs, recent events, and sync timestamp
    """
    handoffs = []
    HANDOFFS_DIR.mkdir(parents=True, exist_ok=True)

    # Read latest handoffs
    if agent:
        agents_to_check = [agent]
    else:
        agents_to_check = ["claude", "antigravity"]

    for a in agents_to_check:
        latest_file = HANDOFFS_DIR / f"LATEST_{a}.json"
        if latest_file.exists():
            try:
                with open(latest_file, "r") as f:
                    handoff_data = json.load(f)
                    handoffs.append(handoff_data)
            except Exception as e:
                logger.error(f"Failed to read handoff for {a}: {e}")

    # Read recent events
    recent_events = []
    sync_file = SYNC_DIR / f"{agent or 'claude'}_last_sync.json"
    last_sync = None

    if sync_file.exists():
        try:
            with open(sync_file, "r") as f:
                sync_data = json.load(f)
                last_sync = sync_data.get("last_sync")
        except Exception:
            pass

    if EVENTS_FILE.exists():
        try:
            with open(EVENTS_FILE, "r") as f:
                for line in f:
                    line = line.strip()
                    if not line:
                        continue
                    try:
                        event = json.loads(line)
                        if last_sync:
                            if event.get("timestamp", "") > last_sync:
                                recent_events.append(event)
                        else:
                            recent_events.append(event)
                    except json.JSONDecodeError:
                        continue
        except Exception as e:
            logger.error(f"Failed to read events: {e}")

    # Limit to last 50 events
    recent_events = recent_events[-50:]

    # Update sync timestamp
    now = datetime.utcnow().isoformat()
    try:
        sync_file.parent.mkdir(parents=True, exist_ok=True)
        with open(sync_file, "w") as f:
            json.dump({"last_sync": now}, f)
    except Exception as e:
        logger.error(f"Failed to update sync timestamp: {e}")

    return json.dumps({
        "handoffs": handoffs,
        "recent_events": recent_events,
        "events_count": len(recent_events),
        "synced_at": now,
        "last_sync": last_sync
    })
