"""Tests for QQ channel ack_message feature.

Covers the four verification points from the PR:
1. C2C message: ack appears instantly
2. Group message: ack appears instantly
3. ack_message set to "": no ack sent
4. Custom ack_message text: correct text delivered
Each test also verifies that normal message processing is not blocked.
"""

from types import SimpleNamespace

import pytest

try:
    from nanobot.channels import qq

    QQ_AVAILABLE = getattr(qq, "QQ_AVAILABLE", False)
except ImportError:
    QQ_AVAILABLE = False

if not QQ_AVAILABLE:
    pytest.skip("QQ dependencies not installed (qq-botpy)", allow_module_level=True)

from nanobot.bus.queue import MessageBus
from nanobot.channels.qq.runtime import QQChannel, QQConfig


class _FakeApi:
    def __init__(self) -> None:
        self.c2c_calls: list[dict] = []
        self.group_calls: list[dict] = []

    async def post_c2c_message(self, **kwargs) -> None:
        self.c2c_calls.append(kwargs)

    async def post_group_message(self, **kwargs) -> None:
        self.group_calls.append(kwargs)


class _FakeClient:
    def __init__(self) -> None:
        self.api = _FakeApi()


@pytest.mark.asyncio
async def test_ack_sent_on_c2c_message() -> None:
    """Ack is sent immediately for C2C messages, then normal processing continues."""
    channel = QQChannel(
        QQConfig(
            app_id="app",
            secret="secret",
            allow_from=["*"],
            ack_message="⏳ Processing...",
        ),
        MessageBus(),
    )
    channel._client = _FakeClient()

    data = SimpleNamespace(
        id="msg1",
        content="hello",
        author=SimpleNamespace(user_openid="user1"),
        attachments=[],
    )
    await channel._on_message(data, is_group=False)

    assert len(channel._client.api.c2c_calls) >= 1
    ack_call = channel._client.api.c2c_calls[0]
    assert ack_call["content"] == "⏳ Processing..."
    assert ack_call["openid"] == "user1"
    assert ack_call["msg_id"] == "msg1"
    assert ack_call["msg_type"] == 0

    msg = await channel.bus.consume_inbound()
    assert msg.content == "hello"
    assert msg.sender_id == "user1"


@pytest.mark.asyncio
async def test_ack_sent_on_group_message() -> None:
    """Ack is sent immediately for group messages, then normal processing continues."""
    channel = QQChannel(
        QQConfig(
            app_id="app",
            secret="secret",
            allow_from=["*"],
            ack_message="⏳ Processing...",
        ),
        MessageBus(),
    )
    channel._client = _FakeClient()

    data = SimpleNamespace(
        id="msg2",
        content="hello group",
        group_openid="group123",
        author=SimpleNamespace(member_openid="user1"),
        attachments=[],
    )
    await channel._on_message(data, is_group=True)

    assert len(channel._client.api.group_calls) >= 1
    ack_call = channel._client.api.group_calls[0]
    assert ack_call["content"] == "⏳ Processing..."
    assert ack_call["group_openid"] == "group123"
    assert ack_call["msg_id"] == "msg2"
    assert ack_call["msg_type"] == 0

    msg = await channel.bus.consume_inbound()
    assert msg.content == "hello group"
    assert msg.chat_id == "group123"


@pytest.mark.asyncio
async def test_no_ack_when_ack_message_empty() -> None:
    """Setting ack_message to empty string disables the ack entirely."""
    channel = QQChannel(
        QQConfig(
            app_id="app",
            secret="secret",
            allow_from=["*"],
            ack_message="",
        ),
        MessageBus(),
    )
    channel._client = _FakeClient()

    data = SimpleNamespace(
        id="msg3",
        content="hello",
        author=SimpleNamespace(user_openid="user1"),
        attachments=[],
    )
    await channel._on_message(data, is_group=False)

    assert len(channel._client.api.c2c_calls) == 0
    assert len(channel._client.api.group_calls) == 0

    msg = await channel.bus.consume_inbound()
    assert msg.content == "hello"


@pytest.mark.asyncio
async def test_custom_ack_message_text() -> None:
    """Custom Chinese ack_message text is delivered correctly."""
    custom = "正在处理中，请稍候..."
    channel = QQChannel(
        QQConfig(
            app_id="app",
            secret="secret",
            allow_from=["*"],
            ack_message=custom,
        ),
        MessageBus(),
    )
    channel._client = _FakeClient()

    data = SimpleNamespace(
        id="msg4",
        content="test input",
        author=SimpleNamespace(user_openid="user1"),
        attachments=[],
    )
    await channel._on_message(data, is_group=False)

    assert len(channel._client.api.c2c_calls) >= 1
    ack_call = channel._client.api.c2c_calls[0]
    assert ack_call["content"] == custom

    msg = await channel.bus.consume_inbound()
    assert msg.content == "test input"
