from __future__ import annotations

import asyncio
from types import SimpleNamespace

from openclaw_lite.interfaces.telegram_bot import ParsedCommand, TelegramBotInterface


class DummySession:
    def __init__(self, session_id: str, chat_id: str, user_id: int | None):
        self.session_id = session_id
        self.chat_id = chat_id
        self.user_id = user_id
        self.provider = "openai"
        self.model = "gpt-4.1-mini"
        self.security_mode = "safe"
        self.history = []
        self.closed = False
        self.metadata = {}


class DummyRuntime:
    def __init__(self):
        self.config = {"telegram": {"bot_token": "123456:TESTTOKEN"}}
        self.telegram_bot = None
        self._session = DummySession("telegram:100:main", "100", 42)
        self.reset_calls: list[str] = []

    def add_tool_registrar(self, registrar):
        return None

    def auth_is_owner(self, *, user_id=None, chat_id=None):
        return user_id == 42

    def auth_is_allowed(self, *, user_id=None, chat_id=None):
        return user_id == 42

    def get_session(self, *, session_id: str, chat_id: str, user_id: int | None):
        self._session.session_id = session_id
        self._session.chat_id = chat_id
        self._session.user_id = user_id
        return self._session

    def provider_summary_payload(self):
        return [
            {
                "name": "openai",
                "type": "openai",
                "enabled": True,
                "has_api_key": True,
                "default_model": "gpt-4.1-mini",
                "is_default": True,
            }
        ]

    def set_provider(self, session, provider_name: str):
        session.provider = provider_name
        return {"provider": provider_name, "model": session.model}

    def set_model(self, session, model: str):
        session.model = model
        return {"provider": session.provider, "model": model}

    def set_provider_api_key(self, provider_name: str, api_key: str):
        return {"provider": provider_name, "has_api_key": bool(api_key)}

    def set_provider_default_model(self, provider_name: str, model: str):
        return {"provider": provider_name, "default_model": model}

    def reset_session(self, session_id: str):
        self.reset_calls.append(session_id)
        return {"session_id": session_id, "reset": True}


class DummyMessage:
    def __init__(self, *, chat_id: int, user_id: int, text: str | None = None):
        self.chat = SimpleNamespace(id=chat_id, title="Demo chat")
        self.from_user = SimpleNamespace(id=user_id, username="demo", full_name="Demo User")
        self.text = text
        self.caption = None
        self.message_id = 1
        self.message_thread_id = None
        self.reply_to_message = None
        self.photo = None
        self.document = None
        self.video = None
        self.animation = None
        self.audio = None
        self.voice = None
        self.sticker = None
        self.replies: list[str] = []

    async def reply(self, text: str, **kwargs):
        self.replies.append(text)
        return self


class DummyCallback:
    def __init__(self, *, data: str, message: DummyMessage, user_id: int):
        self.data = data
        self.message = message
        self.from_user = SimpleNamespace(id=user_id, username="owner", full_name="Owner")
        self.answers: list[tuple[str | None, bool]] = []

    async def answer(self, text: str | None = None, show_alert: bool = False, **kwargs):
        self.answers.append((text, show_alert))


async def _handle_command(interface: TelegramBotInterface, message: DummyMessage, command: ParsedCommand) -> bool:
    return await interface.handle_command(message, command)


async def _handle_callback(interface: TelegramBotInterface, callback: DummyCallback) -> None:
    await interface.handle_callback(callback)


def test_settings_callback_uses_callback_user_for_owner_and_pending_input() -> None:
    runtime = DummyRuntime()
    interface = TelegramBotInterface(runtime)
    bot_message = DummyMessage(chat_id=100, user_id=999)
    callback = DummyCallback(data="settings:key:openai", message=bot_message, user_id=42)

    asyncio.run(_handle_callback(interface, callback))

    assert callback.answers == [(None, False)]
    assert interface.pending_inputs[(100, 42)] == {"action": "api_key", "provider": "openai"}
    assert (100, 999) not in interface.pending_inputs
    assert any("API key" in reply for reply in bot_message.replies)


def test_reset_command_resets_current_session_and_clears_pending_input() -> None:
    runtime = DummyRuntime()
    interface = TelegramBotInterface(runtime)
    message = DummyMessage(chat_id=100, user_id=42, text="/reset")
    interface.pending_inputs[(100, 42)] = {"action": "api_key", "provider": "openai"}

    handled = asyncio.run(_handle_command(interface, message, ParsedCommand(name="reset")))

    assert handled is True
    assert runtime.reset_calls == ["telegram:100:main"]
    assert (100, 42) not in interface.pending_inputs
    assert any("Session reset" in reply for reply in message.replies)
