from a2a.types import (
    AgentCard,
    Message,
)

from a2a_acl.a2a_utils.send_message import (
    build_message,
    SendMessageThread,
    default_message_handler,
    default_artifact_update_handler,
    default_status_update_handler,
    send_message,
    default_error_callback,
)
from a2a_acl.protocol_extension.message_codec import add_illocution


def build_acl_message(illocution: str, content: str, codec: str) -> Message:
    msg = build_message(content)
    msg = add_illocution(msg, illocution, codec)
    return msg


async def send_acl_message(
    destination: AgentCard | str,
    illocution: str,
    content: str,
    sender: str,
    codec: str,
    message_callback=default_message_handler,
    artifact_update_callback=default_artifact_update_handler,
    status_update_callback=default_status_update_handler,
) -> Message:
    """Send *text* to the target agent via the A2A ``message/send`` operation.

    Args:
        destination: card or url of the target agent.
        illocution : illocution such as 'tell' or 'achieve'
        content: Payload to send as a plain-text message.
        sender: the url of sender's server for asynchronous replies.
        codec: the codec used to code the content of the message.
        message_callback: the processor used to process the 'message' text parts.
        artifact_update_callback: the processor used to process the 'task' text parts.
        status_update_callback : the processor used to process the 'status' updates.

    Returns:
        The Message sent.
    """
    msg = build_acl_message(illocution, content, codec)

    await send_message(
        destination,
        msg,
        sender,
        message_callback,
        artifact_update_callback,
        status_update_callback,
    )
    return msg


def spawn_send_acl_message(
    dest: AgentCard | str,
    illocution: str,
    content: str,
    sender: str,
    codec: str,
    message_callback=default_message_handler,
    artifact_update_callback=default_artifact_update_handler,
    status_update_callback=default_status_update_handler,
    error_callback=default_error_callback,
) -> Message:
    msg = build_acl_message(illocution, content, codec)
    t = SendMessageThread(
        dest,
        msg,
        sender,
        error_callback,
        message_callback,
        artifact_update_callback,
        status_update_callback,
    )
    t.start()
    return msg
