"""
Node Identity Service
=====================
Exports/imports identity cards and manages the peer node registry.

An identity card is a JSON dict:
    {node_id, display_name, public_key_b64, endpoint, capabilities, version}

QR code encodes the full card JSON so peers can scan and import easily.
"""

import json
import io
import os
from datetime import datetime, timezone
from pathlib import Path
from typing import Optional

from services.mcp_service import get_node_id, get_public_key_b64

_VERSION = "biznode/1.0"
_IDENTITY_DIR = Path(__file__).parent.parent / "identity"


def build_capabilities() -> list:
    """Return list of capability strings this node supports."""
    caps = ["task_runner", "mcp_auth", "peer_sync"]
    # Check optional services
    try:
        import qdrant_client  # noqa: F401
        caps.append("vector_search")
    except ImportError:
        pass
    return caps


def get_identity_card() -> dict:
    """Return this node's full identity card as a dict."""
    endpoint = os.environ.get("BIZNODE_ENDPOINT", "")
    display_name = os.environ.get("BIZNODE_DISPLAY_NAME", f"BizNode-{get_node_id()[:8]}")

    card = {
        "node_id": get_node_id(),
        "display_name": display_name,
        "public_key_b64": get_public_key_b64(),
        "endpoint": endpoint,
        "capabilities": build_capabilities(),
        "version": _VERSION,
    }

    # Include published tools if available
    try:
        from services.tool_publishing_service import ToolPublishingService
        svc = ToolPublishingService()
        card["published_tools"] = svc.get_tools_for_identity()
    except Exception:
        card["published_tools"] = []

    return card


def export_identity_json() -> str:
    """Return the identity card serialised as a JSON string."""
    return json.dumps(get_identity_card(), indent=2)


def generate_qr_png(endpoint: str = "") -> bytes:
    """
    Generate a QR code PNG of the identity card JSON.
    Returns raw PNG bytes.
    Requires qrcode[pil] and Pillow.
    """
    import qrcode
    from PIL import Image

    card = get_identity_card()
    if endpoint:
        card["endpoint"] = endpoint

    data = json.dumps(card, separators=(",", ":"))
    qr = qrcode.QRCode(
        version=None,
        error_correction=qrcode.constants.ERROR_CORRECT_L,
        box_size=8,
        border=4,
    )
    qr.add_data(data)
    qr.make(fit=True)

    img: Image.Image = qr.make_image(fill_color="black", back_color="white")
    buf = io.BytesIO()
    img.save(buf, format="PNG")
    return buf.getvalue()


def import_peer_card(card_json: str) -> bool:
    """
    Parse and store a peer's identity card in trusted_nodes.

    Returns True on success, False if the card is malformed or missing fields.
    """
    try:
        card = json.loads(card_json) if isinstance(card_json, str) else card_json
    except Exception:
        return False

    required = {"node_id", "public_key_b64"}
    if not required.issubset(card.keys()):
        return False

    # Don't add ourselves
    if card["node_id"] == get_node_id():
        return False

    try:
        import importlib.util
        db_path = Path(__file__).parent.parent / "memory" / "database.py"
        spec = importlib.util.spec_from_file_location("_db", db_path)
        db = importlib.util.module_from_spec(spec)
        spec.loader.exec_module(db)

        caps = card.get("capabilities", [])
        caps_json = json.dumps(caps) if isinstance(caps, list) else caps

        db.register_trusted_node(
            node_id=card["node_id"],
            public_key_b64=card["public_key_b64"],
            display_name=card.get("display_name"),
            endpoint=card.get("endpoint"),
            capabilities=caps_json,
        )
        return True
    except Exception:
        return False
