from datetime import datetime
from pathlib import Path

import sys

from src.chat.message_receive.message import SessionMessage
from src.common.data_models.mai_message_data_model import GroupInfo, MessageInfo, UserInfo
from src.common.data_models.message_component_data_model import (
    ForwardComponent,
    ForwardNodeComponent,
    ImageComponent,
    MessageSequence,
    ReplyComponent,
    TextComponent,
    VoiceComponent,
)
from src.plugin_runtime.host.message_utils import PluginMessageUtils


PROJECT_ROOT = Path(__file__).resolve().parents[1]
if str(PROJECT_ROOT) not in sys.path:
    sys.path.insert(0, str(PROJECT_ROOT))


def test_plugin_message_utils_preserves_binary_components_and_reply_metadata() -> None:
    message = SessionMessage(message_id="msg-1", timestamp=datetime.now(), platform="qq")
    message.message_info = MessageInfo(
        user_info=UserInfo(user_id="10001", user_nickname="tester"),
        group_info=GroupInfo(group_id="20001", group_name="group"),
        additional_config={"self_id": "999"},
    )
    message.session_id = "qq:20001:10001"
    message.processed_plain_text = "binary payload"
    message.raw_message = MessageSequence(
        components=[
            TextComponent("hello"),
            ImageComponent(binary_hash="", binary_data=b"image-bytes", content=""),
            VoiceComponent(binary_hash="", binary_data=b"voice-bytes", content=""),
            ReplyComponent(
                target_message_id="origin-1",
                target_message_content="origin text",
                target_message_sender_id="42",
                target_message_sender_nickname="alice",
                target_message_sender_cardname="Alice",
            ),
            ForwardNodeComponent(
                forward_components=[
                    ForwardComponent(
                        user_nickname="bob",
                        user_id="43",
                        user_cardname="Bob",
                        message_id="forward-1",
                        content=[
                            TextComponent("node-text"),
                            ImageComponent(binary_hash="", binary_data=b"node-image", content=""),
                        ],
                    )
                ]
            ),
        ]
    )

    message_dict = PluginMessageUtils._session_message_to_dict(message)
    rebuilt_message = PluginMessageUtils._build_session_message_from_dict(dict(message_dict))

    image_component = rebuilt_message.raw_message.components[1]
    voice_component = rebuilt_message.raw_message.components[2]
    reply_component = rebuilt_message.raw_message.components[3]
    forward_component = rebuilt_message.raw_message.components[4]

    assert isinstance(image_component, ImageComponent)
    assert image_component.binary_data == b"image-bytes"

    assert isinstance(voice_component, VoiceComponent)
    assert voice_component.binary_data == b"voice-bytes"

    assert isinstance(reply_component, ReplyComponent)
    assert reply_component.target_message_id == "origin-1"
    assert reply_component.target_message_content == "origin text"
    assert reply_component.target_message_sender_id == "42"
    assert reply_component.target_message_sender_nickname == "alice"
    assert reply_component.target_message_sender_cardname == "Alice"

    assert isinstance(forward_component, ForwardNodeComponent)
    assert isinstance(forward_component.forward_components[0].content[1], ImageComponent)
    assert forward_component.forward_components[0].content[1].binary_data == b"node-image"
