"""
Telegram MCP - Thin stdio client for Telegram communication.

Enables AI agents to communicate with users via Telegram.
Uses polling for replies to work around proxy timeouts.
"""

import asyncio
import logging
import os
import sys

import httpx
from mcp.server.fastmcp import FastMCP

logging.basicConfig(level=logging.INFO, stream=sys.stderr)
logger = logging.getLogger(__name__)

# Configuration
SERVER_URL = os.environ.get("TELEGRAM_SERVER_URL", "https://telegram-mcp.furkankucuk.net")
CHAT_ID = os.environ.get("TELEGRAM_CHAT_ID")
POLL_INTERVAL = 5  # seconds between polls

# MCP Server
mcp = FastMCP(
    name="Telegram MCP",
    instructions="""
Send messages to the user via Telegram with interact().
Use it for ALL communication when user prefers Telegram.
When done: interact("Done! What's next?", wait_for_reply=True)
""",
)


async def _poll_for_reply(client: httpx.AsyncClient, request_id: str) -> dict:
    """Poll the server until we get a reply."""
    while True:
        response = await client.get(
            f"{SERVER_URL}/api/poll",
            headers={"X-Chat-Id": CHAT_ID},
            params={"request_id": request_id},
        )
        
        if response.status_code != 200:
            raise RuntimeError(f"Poll error: {response.text}")
        
        data = response.json()
        
        if data.get("status") == "completed":
            return data.get("reply", {})
        
        await asyncio.sleep(POLL_INTERVAL)


@mcp.tool()
async def interact(
    message: str | None = None,
    wait_for_reply: bool = False,
    choices: list[str] | None = None,
    media_type: str | None = None,
    media_url: str | None = None,
) -> dict:
    """
    Send a message or media to the user via Telegram.

    Args:
        message: Text message to send. Can be combined with media.
        wait_for_reply: If True, block until user replies.
        choices: Button labels for quick replies.
        media_type: Type of media - "photo", "video", "audio", or "document".
        media_url: URL of the media file to send.

    Returns:
        For text replies: {"reply": "user's text"}
        For media replies: {"reply": {"text": "caption", "media": {"type": "photo", "url": "..."}}}
        When not waiting: {"reply": None, "message_id": 123}

    Examples:
        # Simple text message
        interact("Working on it...")
        
        # Wait for reply
        result = interact("What should I do?", wait_for_reply=True)
        
        # Yes/No buttons
        result = interact("Delete?", choices=["Yes", "No"], wait_for_reply=True)
        
        # Send a photo with caption
        interact("Here's the result:", media_type="photo", media_url="https://...")
        
        # Send a document
        interact(media_type="document", media_url="https://.../report.pdf")
    """
    if not CHAT_ID:
        raise RuntimeError("TELEGRAM_CHAT_ID environment variable required")
    
    if not message and not media_url:
        raise ValueError("Either message or media_url must be provided")

    async with httpx.AsyncClient(timeout=120) as client:
        response = await client.post(
            f"{SERVER_URL}/api/interact",
            headers={"X-Chat-Id": CHAT_ID},
            json={
                "message": message,
                "wait_for_reply": wait_for_reply,
                "choices": choices,
                "media_type": media_type,
                "media_url": media_url,
            },
        )
        
        if response.status_code != 200:
            raise RuntimeError(f"Server error: {response.text}")
        
        data = response.json()
        
        if not wait_for_reply:
            return {"reply": None, "message_id": data.get("message_id")}
        
        request_id = data.get("request_id")
        if not request_id:
            return {"reply": None}
        
        reply = await _poll_for_reply(client, request_id)
        return {"reply": reply}


@mcp.tool()
async def get_messages(limit: int = 10) -> dict:
    """
    Get recent Telegram conversation history.

    Args:
        limit: Number of messages (1-50, default 10).

    Returns:
        messages: List of recent messages with text and media info.
    """
    if not CHAT_ID:
        raise RuntimeError("TELEGRAM_CHAT_ID environment variable required")

    async with httpx.AsyncClient(timeout=30) as client:
        response = await client.get(
            f"{SERVER_URL}/api/messages",
            headers={"X-Chat-Id": CHAT_ID},
            params={"limit": limit},
        )
        
        if response.status_code != 200:
            raise RuntimeError(f"Server error: {response.text}")
        
        return response.json()


def main():
    """Run the MCP server."""
    if not CHAT_ID:
        logger.error("TELEGRAM_CHAT_ID environment variable required")
        sys.exit(1)
    
    logger.info(f"Starting Telegram MCP (server: {SERVER_URL}, chat_id: {CHAT_ID})")
    mcp.run(transport="stdio")


if __name__ == "__main__":
    main()
