from __future__ import annotations

from datetime import datetime, timezone
from unittest.mock import MagicMock, PropertyMock

import pytest

from mrp.models import (
    AgentInfo,
    Blob,
    DiscoveredAgent,
    Message,
    MessageStatus,
    PollResult,
    SendResult,
)
from mrp_mcp.state import SessionState


def _now():
    return datetime.now(timezone.utc)


@pytest.fixture
def state():
    return SessionState()


@pytest.fixture
def mock_client():
    client = MagicMock()

    client.get_agent.return_value = AgentInfo(
        public_key="test-pk-1234567890abcdefghijklmnopqrstuv",
        display_name="Test Agent",
        status="active",
        metadata={},
        capabilities=["text:chat"],
        created_at=_now(),
        last_active_at=_now(),
    )

    client.update_agent.return_value = AgentInfo(
        public_key="test-pk-1234567890abcdefghijklmnopqrstuv",
        display_name="Updated Agent",
        status="active",
        metadata={},
        capabilities=["text:chat", "text:summarize"],
        created_at=_now(),
        last_active_at=_now(),
    )

    client.poll_messages.return_value = PollResult(messages=[], next_cursor=None)

    client.send_message.return_value = SendResult(
        message_id="msg_001",
        status="sent",
        created_at=_now(),
        expires_at=_now(),
    )

    client.get_message.return_value = Message(
        message_id="msg_001",
        sender_key="sender-pk-abcdefghijklmnopqrstuvwxyz1234",
        recipient_key="test-pk-1234567890abcdefghijklmnopqrstuv",
        content_type="application/json",
        body={"text": "Hello!"},
        attachments=[],
        status="sent",
        thread_id=None,
        in_reply_to=None,
        metadata={},
        created_at=_now(),
        expires_at=_now(),
    )

    client.get_message_status.return_value = MessageStatus(
        status="delivered",
        created_at=_now(),
        delivered_at=_now(),
        expires_at=_now(),
    )

    client.get_thread.return_value = PollResult(messages=[], next_cursor=None)

    client.upload_blob.return_value = Blob(
        blob_id="blob_001",
        hash="abc123",
        size=1024,
        content_type="application/octet-stream",
        created_at=_now(),
        expires_at=_now(),
    )

    client.download_blob.return_value = (b"file-content", "application/octet-stream")

    return client


@pytest.fixture
def mock_agent(mock_client):
    agent = MagicMock()
    agent.client = mock_client
    type(agent).public_key = PropertyMock(
        return_value="test-pk-1234567890abcdefghijklmnopqrstuv"
    )

    _discover_results = [
        DiscoveredAgent(
            public_key="agent-pk-abcdefghijklmnopqrstuvwxyz12345",
            display_name="TranslatorBot",
            last_active_at=_now(),
            capabilities=["text:translate"],
        ),
    ]
    agent.discover.return_value = _discover_results
    agent.discover_search.return_value = _discover_results

    agent.send.return_value = SendResult(
        message_id="msg_002",
        status="sent",
        created_at=_now(),
        expires_at=_now(),
    )

    agent.reply.return_value = SendResult(
        message_id="msg_003",
        status="sent",
        created_at=_now(),
        expires_at=_now(),
    )

    agent.upload.return_value = Blob(
        blob_id="blob_001",
        hash="abc123",
        size=1024,
        content_type="application/octet-stream",
        created_at=_now(),
        expires_at=_now(),
    )

    agent.download.return_value = (b"file-content", "application/octet-stream")

    return agent


@pytest.fixture
def sample_agents():
    return [
        DiscoveredAgent(
            public_key="pk-agent-a-abcdefghijklmnopqrstuvwx",
            display_name="Agent Alpha",
            last_active_at=_now(),
            capabilities=["text:chat", "text:summarize"],
        ),
        DiscoveredAgent(
            public_key="pk-agent-b-abcdefghijklmnopqrstuvwx",
            display_name="Agent Beta",
            last_active_at=_now(),
            capabilities=["code:review"],
        ),
    ]


@pytest.fixture
def sample_messages():
    return [
        Message(
            message_id="msg_100",
            sender_key="sender-pk-abcdefghijklmnopqrstuvwxyz1234",
            recipient_key="test-pk-1234567890abcdefghijklmnopqrstuv",
            content_type="application/json",
            body={"text": "Hello there!"},
            attachments=[],
            status="sent",
            thread_id="thread-1",
            in_reply_to=None,
            metadata={},
            created_at=_now(),
            expires_at=_now(),
        ),
        Message(
            message_id="msg_101",
            sender_key="sender-pk-abcdefghijklmnopqrstuvwxyz1234",
            recipient_key="test-pk-1234567890abcdefghijklmnopqrstuv",
            content_type="application/json",
            body={"text": "How are you?"},
            attachments=[],
            status="sent",
            thread_id="thread-1",
            in_reply_to="msg_100",
            metadata={},
            created_at=_now(),
            expires_at=_now(),
        ),
    ]
