from __future__ import annotations

from adapter.matrix.handlers.confirm import make_handle_cancel, make_handle_confirm
from adapter.matrix.store import get_pending_confirm, set_pending_confirm
from core.auth import AuthManager
from core.chat import ChatManager
from core.protocol import IncomingCallback, OutgoingMessage
from core.settings import SettingsManager
from core.store import InMemoryStore
from sdk.mock import MockPlatformClient


async def test_mat09_yes_reads_pending_confirm():
    store = InMemoryStore()
    platform = MockPlatformClient()
    chat_mgr = ChatManager(platform, store)
    auth_mgr = AuthManager(platform, store)
    settings_mgr = SettingsManager(platform, store)

    await set_pending_confirm(
        store,
        "@alice:example.org",
        "!confirm:example.org",
        {
            "action_id": "delete_file",
            "description": "Удалить файл config.yaml",
            "payload": {},
        },
    )

    handler = make_handle_confirm(store)
    event = IncomingCallback(
        user_id="@alice:example.org",
        platform="matrix",
        chat_id="C7",
        action="confirm",
        payload={"source": "command", "command": "yes", "room_id": "!confirm:example.org"},
    )
    result = await handler(event, auth_mgr, platform, chat_mgr, settings_mgr)

    assert len(result) == 1
    assert isinstance(result[0], OutgoingMessage)
    assert "Удалить файл config.yaml" in result[0].text
    assert await get_pending_confirm(store, "@alice:example.org", "!confirm:example.org") is None


async def test_no_clears_pending_confirm():
    store = InMemoryStore()
    platform = MockPlatformClient()
    chat_mgr = ChatManager(platform, store)
    auth_mgr = AuthManager(platform, store)
    settings_mgr = SettingsManager(platform, store)

    await set_pending_confirm(
        store,
        "@alice:example.org",
        "!confirm:example.org",
        {
            "action_id": "delete_file",
            "description": "Удалить файл",
            "payload": {},
        },
    )

    handler = make_handle_cancel(store)
    event = IncomingCallback(
        user_id="@alice:example.org",
        platform="matrix",
        chat_id="C7",
        action="cancel",
        payload={"source": "command", "command": "no", "room_id": "!confirm:example.org"},
    )
    result = await handler(event, auth_mgr, platform, chat_mgr, settings_mgr)

    assert len(result) == 1
    assert "отменено" in result[0].text.lower()
    assert await get_pending_confirm(store, "@alice:example.org", "!confirm:example.org") is None


async def test_yes_without_pending_returns_no_pending():
    store = InMemoryStore()
    platform = MockPlatformClient()
    chat_mgr = ChatManager(platform, store)
    auth_mgr = AuthManager(platform, store)
    settings_mgr = SettingsManager(platform, store)

    handler = make_handle_confirm(store)
    event = IncomingCallback(
        user_id="@alice:example.org",
        platform="matrix",
        chat_id="C1",
        action="confirm",
        payload={},
    )
    result = await handler(event, auth_mgr, platform, chat_mgr, settings_mgr)

    assert len(result) == 1
    assert "Нет ожидающих" in result[0].text


async def test_yes_falls_back_to_legacy_chat_key_without_room_payload():
    store = InMemoryStore()
    platform = MockPlatformClient()
    chat_mgr = ChatManager(platform, store)
    auth_mgr = AuthManager(platform, store)
    settings_mgr = SettingsManager(platform, store)

    await set_pending_confirm(
        store,
        "legacy-chat",
        {
            "action_id": "delete_file",
            "description": "Legacy confirm",
            "payload": {},
        },
    )

    handler = make_handle_confirm(store)
    event = IncomingCallback(
        user_id="@alice:example.org",
        platform="matrix",
        chat_id="legacy-chat",
        action="confirm",
        payload={"source": "command", "command": "yes"},
    )
    result = await handler(event, auth_mgr, platform, chat_mgr, settings_mgr)

    assert len(result) == 1
    assert "Legacy confirm" in result[0].text
    assert await get_pending_confirm(store, "legacy-chat") is None
