#!/usr/bin/env python3
"""Team Board Agent — Coder.

Connects to Tracker via WebSocket, listens for tasks, executes them via OpenClaw.
"""

import asyncio
import json
import logging
import signal
import sys

import websockets

from config import (
    TRACKER_WS_URL,
    AGENT_TOKEN,
    AGENT_NAME,
    AGENT_SLUG,
    HEARTBEAT_INTERVAL,
)
from brain import think

logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s %(levelname)s %(name)s: %(message)s",
)
logger = logging.getLogger("agent")

# State
current_tasks: list[str] = []
status = "idle"
running = True


async def send_json(ws, data: dict):
    await ws.send(json.dumps(data))


async def heartbeat(ws):
    """Send periodic heartbeat to Tracker."""
    while running:
        try:
            await send_json(ws, {
                "event": "agent.heartbeat",
                "status": status,
                "current_tasks": current_tasks,
            })
        except Exception:
            break
        await asyncio.sleep(HEARTBEAT_INTERVAL)


async def handle_task_assigned(ws, data: dict):
    """Handle an assigned task — execute it."""
    global status
    task_id = data.get("task_id")
    task_title = data.get("title", "Без названия")
    task_description = data.get("description")
    project_name = data.get("project_name", "")

    logger.info("Task assigned: %s — %s", task_id, task_title)

    status = "busy"
    current_tasks.append(task_id)

    try:
        # Take the task
        await send_json(ws, {"event": "task.take", "task_id": task_id})

        # Think (send to OpenClaw)
        result = await think(task_title, task_description, project_name)

        # Post result as comment
        await send_json(ws, {
            "event": "task.comment",
            "task_id": task_id,
            "content": result,
            "sender_type": "agent",
            "sender_name": AGENT_NAME,
        })

        # Complete the task
        await send_json(ws, {"event": "task.complete", "task_id": task_id})
        logger.info("Task completed: %s", task_id)

    except Exception as e:
        logger.error("Error processing task %s: %s", task_id, e)
        # Comment the error
        await send_json(ws, {
            "event": "task.comment",
            "task_id": task_id,
            "content": f"❌ Ошибка: {e}",
            "sender_type": "agent",
            "sender_name": AGENT_NAME,
        })
    finally:
        if task_id in current_tasks:
            current_tasks.remove(task_id)
        status = "idle" if not current_tasks else "busy"


async def handle_chat_message(ws, data: dict):
    """Handle incoming chat message — respond if mentioned."""
    content = data.get("content", "")
    sender_name = data.get("sender_name", "")
    chat_id = data.get("chat_id")

    # Only respond if mentioned
    if f"@{AGENT_SLUG}" not in content and f"@{AGENT_NAME}" not in content.lower():
        return

    logger.info("Mentioned in chat by %s: %s", sender_name, content[:100])

    # Simple response via brain
    result = await think(
        f"Сообщение от {sender_name}: {content}",
        None,
        "чат",
    )

    await send_json(ws, {
        "event": "chat.send",
        "chat_id": chat_id,
        "content": result,
        "sender_type": "agent",
        "sender_name": AGENT_NAME,
    })


async def connect():
    """Main connection loop with auto-reconnect."""
    while running:
        try:
            url = f"{TRACKER_WS_URL}?client_type=agent&client_id={AGENT_SLUG}"
            logger.info("Connecting to Tracker: %s", url)

            async with websockets.connect(url) as ws:
                logger.info("Connected to Tracker ✅")

                # Auth
                await send_json(ws, {
                    "event": "auth",
                    "token": AGENT_TOKEN,
                })

                # Start heartbeat
                hb_task = asyncio.create_task(heartbeat(ws))

                try:
                    async for raw in ws:
                        try:
                            msg = json.loads(raw)
                        except json.JSONDecodeError:
                            continue

                        event = msg.get("event")
                        logger.debug("Event: %s", event)

                        if event == "auth.ok":
                            logger.info("Authenticated. Init: %s", json.dumps(msg.get("init", {}), ensure_ascii=False)[:200])

                        elif event == "task.assigned":
                            asyncio.create_task(handle_task_assigned(ws, msg))

                        elif event == "chat.message":
                            asyncio.create_task(handle_chat_message(ws, msg))

                        elif event == "agent.heartbeat.ack":
                            pass  # OK

                        elif event == "error":
                            logger.warning("Error from Tracker: %s", msg.get("message"))

                        else:
                            logger.debug("Unhandled event: %s", event)

                finally:
                    hb_task.cancel()

        except (websockets.ConnectionClosed, ConnectionRefusedError, OSError) as e:
            logger.warning("Connection lost: %s. Reconnecting in 5s...", e)
            await asyncio.sleep(5)
        except Exception as e:
            logger.error("Unexpected error: %s. Reconnecting in 10s...", e)
            await asyncio.sleep(10)


def main():
    global running

    def stop(*_):
        global running
        running = False
        logger.info("Shutting down...")

    signal.signal(signal.SIGINT, stop)
    signal.signal(signal.SIGTERM, stop)

    logger.info("🤖 Agent '%s' (%s) starting...", AGENT_NAME, AGENT_SLUG)

    if not AGENT_TOKEN:
        logger.error("AGENT_TOKEN is required!")
        sys.exit(1)

    asyncio.run(connect())


if __name__ == "__main__":
    main()
