from __future__ import annotations

import json

from core.protocol import (
    Attachment,
    IncomingCallback,
    IncomingCommand,
    IncomingEvent,
    IncomingMessage,
    OutgoingEvent,
    OutgoingMessage,
    OutgoingNotification,
    OutgoingTyping,
    OutgoingUI,
)

PLATFORM = "web"


def json_to_incoming(data: dict) -> IncomingEvent | None:
    user_id = data.get("user_id", "")
    chat_id = data.get("chat_id", "C1")
    msg_type = data.get("type", "message")

    if msg_type == "command":
        return IncomingCommand(
            user_id=user_id,
            platform=PLATFORM,
            chat_id=chat_id,
            command=data.get("command", ""),
            args=data.get("args", []),
        )

    if msg_type == "callback":
        return IncomingCallback(
            user_id=user_id,
            platform=PLATFORM,
            chat_id=chat_id,
            action=data.get("action", ""),
            payload=data.get("payload", {}),
        )

    if msg_type == "message":
        attachments = []
        for a in data.get("attachments", []):
            attachments.append(
                Attachment(
                    type=a.get("type", "document"),
                    url=a.get("url"),
                    filename=a.get("filename"),
                    mime_type=a.get("mime_type"),
                    workspace_path=a.get("workspace_path"),
                )
            )
        return IncomingMessage(
            user_id=user_id,
            platform=PLATFORM,
            chat_id=chat_id,
            text=data.get("text", ""),
            attachments=attachments,
        )

    return None


def outgoing_to_json(event: OutgoingEvent) -> str:
    if isinstance(event, OutgoingMessage):
        payload = {
            "type": "message",
            "chat_id": event.chat_id,
            "text": event.text,
            "parse_mode": event.parse_mode,
        }
        if event.attachments:
            payload["attachments"] = [
                {
                    "type": a.type,
                    "filename": a.filename or "file",
                    "mime_type": a.mime_type,
                    "download_url": f"/files/{a.workspace_path}" if a.workspace_path else None,
                }
                for a in event.attachments
            ]
        return json.dumps(payload, ensure_ascii=False)

    if isinstance(event, OutgoingUI):
        buttons = [
            {
                "label": b.label,
                "action": b.action,
                "payload": b.payload,
                "style": b.style,
            }
            for b in event.buttons
        ]
        return json.dumps(
            {
                "type": "ui",
                "chat_id": event.chat_id,
                "text": event.text,
                "buttons": buttons,
            },
            ensure_ascii=False,
        )

    if isinstance(event, OutgoingTyping):
        return json.dumps(
            {
                "type": "typing",
                "chat_id": event.chat_id,
                "is_typing": event.is_typing,
            },
            ensure_ascii=False,
        )

    if isinstance(event, OutgoingNotification):
        return json.dumps(
            {
                "type": "notification",
                "chat_id": event.chat_id,
                "text": event.text,
                "level": event.level,
            },
            ensure_ascii=False,
        )

    return json.dumps({"type": "unknown"})
