#!/usr/bin/env python3
# Familiar - Self-Hosted AI Companion Platform
# Copyright (c) 2026 George Scott Foley
# ORCID: 0009-0006-4957-0540
# Email: Georgescottfoley@proton.me
# Licensed under the MIT License - see LICENSE file for details

"""
Familiar Node

Run this on your laptop/desktop to connect to the Pi gateway.
Exposes local tools (clipboard, notifications, etc.) to the agent.

Usage:
    # Interactive mode
    python -m familiar.node --gateway ws://pi.local:18789 --key YOUR_SECRET_KEY

    # Or set environment variables
    export FAMILIAR_GATEWAY="ws://pi.local:18789"
    export FAMILIAR_KEY="your-secret-key"
    python -m familiar.node
"""

import argparse
import asyncio
import logging
import os
import sys

# Setup path
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

from familiar.core.mesh import MeshNode, Message, MsgType
from familiar.core.node_tools import DESKTOP_TOOLS, register_desktop_tools


def setup_logging(verbose: bool = False):
    level = logging.DEBUG if verbose else logging.INFO
    logging.basicConfig(
        level=level, format="%(asctime)s [%(levelname)s] %(message)s", datefmt="%H:%M:%S"
    )


async def interactive_mode(node: MeshNode):
    """Run interactive chat mode."""
    print("\n" + "=" * 50)
    print("  Connected to Familiar Gateway")
    print("  Type messages to chat, or commands:")
    print("    /nodes  - List connected nodes")
    print("    /tools  - List available tools")
    print("    /quit   - Disconnect")
    print("=" * 50 + "\n")

    # Handle responses
    async def on_response(msg: Message):
        print(f"\nAgent: {msg.payload.get('text', '')}\n")
        print("You: ", end="", flush=True)

    node.on_message(MsgType.ASSISTANT_RESPONSE, on_response)

    # Input loop (run in thread)
    loop = asyncio.get_event_loop()

    while True:
        try:
            # Get input in executor to not block
            user_input = await loop.run_in_executor(None, lambda: input("You: "))

            if not user_input.strip():
                continue

            if user_input.startswith("/"):
                cmd = user_input[1:].lower().strip()

                if cmd in ["quit", "exit", "q"]:
                    print("Disconnecting...")
                    await node.disconnect()
                    break

                elif cmd == "nodes":
                    nodes = await node.get_nodes()
                    print("\nConnected nodes:")
                    for n in nodes:
                        print(f"  • {n.get('name', 'unknown')} ({n.get('type', '')})")
                    print()

                elif cmd == "tools":
                    print("\nLocal tools:")
                    for t in DESKTOP_TOOLS:
                        print(f"  • {t['name']}: {t['description']}")
                    print()

                else:
                    print(f"Unknown command: {cmd}")

            else:
                await node.send_message(user_input)

        except EOFError:
            break
        except KeyboardInterrupt:
            print("\nDisconnecting...")
            await node.disconnect()
            break


async def main():
    parser = argparse.ArgumentParser(description="Familiar Node")

    parser.add_argument(
        "--gateway",
        "-g",
        default=os.environ.get("FAMILIAR_GATEWAY", "ws://localhost:18789"),
        help="Gateway WebSocket URL",
    )

    parser.add_argument(
        "--key",
        "-k",
        default=os.environ.get("FAMILIAR_KEY", ""),
        help="Secret key for authentication",
    )

    parser.add_argument(
        "--name",
        "-n",
        default=os.environ.get("FAMILIAR_NODE_NAME", f"{os.uname().nodename}"),
        help="Node name",
    )

    parser.add_argument(
        "--type",
        "-t",
        default="desktop",
        choices=["desktop", "laptop", "server", "mobile"],
        help="Node type",
    )

    parser.add_argument("--verbose", "-v", action="store_true", help="Verbose logging")

    parser.add_argument(
        "--headless", action="store_true", help="Run without interactive mode (just expose tools)"
    )

    args = parser.parse_args()

    setup_logging(args.verbose)

    if not args.key:
        print("Error: Secret key required")
        print("Set FAMILIAR_KEY environment variable or use --key")
        sys.exit(1)

    # Create node
    node = MeshNode(
        gateway_url=args.gateway, secret_key=args.key, name=args.name, node_type=args.type
    )

    # Register desktop tools
    register_desktop_tools(node)

    print(f"Connecting to gateway: {args.gateway}")
    print(f"Node name: {args.name}")
    print(f"Tools: {len(DESKTOP_TOOLS)}")

    if args.headless:
        # Just connect and stay connected
        await node.connect()
    else:
        # Connect and run interactive mode
        connect_task = asyncio.create_task(node.connect())

        # Wait a bit for connection
        await asyncio.sleep(2)

        if node.websocket:
            await interactive_mode(node)
        else:
            print("Failed to connect to gateway")
            connect_task.cancel()


if __name__ == "__main__":
    asyncio.run(main())
