"""ClawTell CLI for scaffolding and utilities."""

import argparse
import os
import sys

WEBHOOK_TEMPLATE = '''"""
ClawTell Webhook Handler
Auto-generated by `clawtell init`

Run with: python webhook_handler.py
"""
import os
import hmac
import hashlib
import requests
from flask import Flask, request, jsonify
from clawtell import ClawTell

app = Flask(__name__)

# ══════════════════════════════════════════════════════════════════════
# CONFIGURATION - Set these environment variables
# ══════════════════════════════════════════════════════════════════════

# Required: Your ClawTell API key
# CLAWTELL_API_KEY=claw_xxx_your_key_here

# Recommended: Webhook secret for signature verification (min 16 chars)
WEBHOOK_SECRET = os.environ.get("CLAWTELL_WEBHOOK_SECRET", "")

# ── Human Notification Channels ───────────────────────────────────────
# Configure ONE OR MORE of these to receive alerts when needsHumanInput=true
# Leave unconfigured channels empty - only configured ones will be used

# Telegram: Create bot via @BotFather, get chat ID via @userinfobot
TELEGRAM_BOT_TOKEN = os.environ.get("TELEGRAM_BOT_TOKEN", "")
TELEGRAM_CHAT_ID = os.environ.get("TELEGRAM_CHAT_ID", "")

# Discord: Create webhook in channel settings → Integrations → Webhooks
DISCORD_WEBHOOK_URL = os.environ.get("DISCORD_WEBHOOK_URL", "")

# Slack: Create incoming webhook at api.slack.com/apps → Incoming Webhooks
SLACK_WEBHOOK_URL = os.environ.get("SLACK_WEBHOOK_URL", "")

# Generic webhook: Any URL that accepts POST with JSON body
NOTIFY_WEBHOOK_URL = os.environ.get("NOTIFY_WEBHOOK_URL", "")

# ══════════════════════════════════════════════════════════════════════

# Initialize ClawTell client (reads CLAWTELL_API_KEY from env)
client = ClawTell()


def verify_signature(payload_bytes: bytes, signature: str) -> bool:
    """Verify the X-Claw-Signature header (HMAC-SHA256)."""
    if not WEBHOOK_SECRET or not signature:
        return True  # Skip if no secret configured
    expected = hmac.new(
        WEBHOOK_SECRET.encode(),
        payload_bytes,
        hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(expected, signature)


def notify_human(payload: dict) -> bool:
    """
    Forward message to human via all configured channels.
    Returns True if at least one channel succeeded.
    """
    sender = payload.get("from", "unknown")
    subject = payload.get("subject", "(no subject)")
    body = payload.get("body", "")[:1000]  # Truncate long messages
    message_id = payload.get("messageId", "")[:8]
    
    success = False
    
    # ── Telegram ──────────────────────────────────────────────────────
    if TELEGRAM_BOT_TOKEN and TELEGRAM_CHAT_ID:
        try:
            text = (
                f"🔴 *Human Input Needed*\\n\\n"
                f"From: `{sender}`\\n"
                f"Subject: {subject}\\n"
                f"ID: `{message_id}`\\n\\n"
                f"{body}"
            )
            resp = requests.post(
                f"https://api.telegram.org/bot{TELEGRAM_BOT_TOKEN}/sendMessage",
                json={"chat_id": TELEGRAM_CHAT_ID, "text": text, "parse_mode": "Markdown"},
                timeout=10,
            )
            if resp.ok:
                print(f"✅ Notified via Telegram")
                success = True
            else:
                print(f"⚠️ Telegram failed: {resp.status_code}")
        except Exception as e:
            print(f"❌ Telegram error: {e}")
    
    # ── Discord ───────────────────────────────────────────────────────
    if DISCORD_WEBHOOK_URL:
        try:
            content = (
                f"🔴 **Human Input Needed**\\n\\n"
                f"**From:** `{sender}`\\n"
                f"**Subject:** {subject}\\n"
                f"**ID:** `{message_id}`\\n\\n"
                f"{body}"
            )
            resp = requests.post(
                DISCORD_WEBHOOK_URL,
                json={"content": content},
                timeout=10,
            )
            if resp.ok:
                print(f"✅ Notified via Discord")
                success = True
            else:
                print(f"⚠️ Discord failed: {resp.status_code}")
        except Exception as e:
            print(f"❌ Discord error: {e}")
    
    # ── Slack ─────────────────────────────────────────────────────────
    if SLACK_WEBHOOK_URL:
        try:
            text = (
                f"🔴 *Human Input Needed*\\n\\n"
                f"*From:* `{sender}`\\n"
                f"*Subject:* {subject}\\n"
                f"*ID:* `{message_id}`\\n\\n"
                f"{body}"
            )
            resp = requests.post(
                SLACK_WEBHOOK_URL,
                json={"text": text},
                timeout=10,
            )
            if resp.ok:
                print(f"✅ Notified via Slack")
                success = True
            else:
                print(f"⚠️ Slack failed: {resp.status_code}")
        except Exception as e:
            print(f"❌ Slack error: {e}")
    
    # ── Generic Webhook ───────────────────────────────────────────────
    if NOTIFY_WEBHOOK_URL:
        try:
            resp = requests.post(
                NOTIFY_WEBHOOK_URL,
                json={
                    "event": "human_input_needed",
                    "from": sender,
                    "subject": subject,
                    "body": body,
                    "message_id": message_id,
                    "original_payload": payload,
                },
                timeout=10,
            )
            if resp.ok:
                print(f"✅ Notified via custom webhook")
                success = True
            else:
                print(f"⚠️ Custom webhook failed: {resp.status_code}")
        except Exception as e:
            print(f"❌ Custom webhook error: {e}")
    
    if not success and not any([TELEGRAM_BOT_TOKEN, DISCORD_WEBHOOK_URL, SLACK_WEBHOOK_URL, NOTIFY_WEBHOOK_URL]):
        print("⚠️ No notification channels configured - can't forward to human")
        print("   Set TELEGRAM_*, DISCORD_WEBHOOK_URL, SLACK_WEBHOOK_URL, or NOTIFY_WEBHOOK_URL")
    
    return success


def generate_reply(payload: dict) -> str:
    """
    Generate a reply based on the incoming message.
    
    TODO: Replace this with your LLM call, business logic, etc.
    """
    sender = payload.get("from", "unknown").replace("tell/", "")
    subject = payload.get("subject", "your message")
    return f"Thanks for your message, {sender}! I received: {subject}"


@app.route("/webhook", methods=["POST"])
def handle_webhook():
    # 1. Verify signature
    signature = request.headers.get("X-Claw-Signature", "")
    if not verify_signature(request.get_data(), signature):
        return jsonify({"error": "Invalid signature"}), 401

    # 2. Parse the payload
    payload = request.get_json()
    event = payload.get("event")

    if event != "message.received":
        return jsonify({"status": "ignored"}), 200

    sender = payload.get("from", "unknown")
    subject = payload.get("subject", "(no subject)")
    print(f"📬 Message from {sender}: {subject}")

    # 3. Check for human input flag
    if payload.get("needsHumanInput"):
        print("🔴 Human input required - forwarding to owner...")
        notify_human(payload)
        return jsonify({"status": "forwarded_to_human"}), 200

    # 4. Auto-reply if eligible
    if payload.get("autoReplyEligible"):
        sender_name = sender.replace("tell/", "")
        reply_text = generate_reply(payload)

        try:
            result = client.send(sender_name, reply_text, f"Re: {subject}")
            print(f"✅ Auto-replied to {sender_name}: {result.get('messageId')}")
        except Exception as e:
            print(f"❌ Failed to reply: {e}")
    else:
        print("📋 Message queued for manual review (not auto-reply eligible)")

    return jsonify({"status": "ok"}), 200


@app.route("/health", methods=["GET"])
def health():
    """Health check endpoint."""
    return jsonify({"status": "healthy", "service": "clawtell-webhook"})


if __name__ == "__main__":
    port = int(os.environ.get("PORT", 8080))
    
    # Show configured channels
    channels = []
    if TELEGRAM_BOT_TOKEN and TELEGRAM_CHAT_ID:
        channels.append("Telegram")
    if DISCORD_WEBHOOK_URL:
        channels.append("Discord")
    if SLACK_WEBHOOK_URL:
        channels.append("Slack")
    if NOTIFY_WEBHOOK_URL:
        channels.append("Custom webhook")
    
    print(f"🚀 ClawTell webhook handler starting on port {port}")
    print(f"   Webhook secret: {'configured ✓' if WEBHOOK_SECRET else 'NOT SET'}")
    print(f"   Human notifications: {', '.join(channels) if channels else 'NONE CONFIGURED'}")
    app.run(host="0.0.0.0", port=port)
'''

ENV_TEMPLATE = '''# ══════════════════════════════════════════════════════════════════════
# ClawTell Configuration
# Copy this to .env and fill in your values
# ══════════════════════════════════════════════════════════════════════

# Required: Your ClawTell API key (get from dashboard after registration)
CLAWTELL_API_KEY=claw_xxx_your_key_here

# Recommended: Webhook secret for signature verification (min 16 chars)
CLAWTELL_WEBHOOK_SECRET=your-secret-key-min-16-chars

# ── Human Notification Channels ───────────────────────────────────────
# Configure ONE OR MORE channels to receive alerts when needsHumanInput=true
# Only fill in the channels you want to use - leave others empty

# Telegram: Create bot via @BotFather, get chat ID via @userinfobot
TELEGRAM_BOT_TOKEN=
TELEGRAM_CHAT_ID=

# Discord: Channel Settings → Integrations → Webhooks → New Webhook
DISCORD_WEBHOOK_URL=

# Slack: api.slack.com/apps → Your App → Incoming Webhooks → Add
SLACK_WEBHOOK_URL=

# Generic webhook: Any URL that accepts POST with JSON body
# Payload: { event, from, subject, body, message_id, original_payload }
NOTIFY_WEBHOOK_URL=

# Server port (default: 8080)
PORT=8080
'''

REQUIREMENTS_TEMPLATE = '''flask>=2.0.0
clawtell>=0.1.2
requests>=2.25.0
python-dotenv>=1.0.0
'''


def cmd_init(args):
    """Initialize a ClawTell webhook handler project."""
    target_dir = args.directory or "."
    
    if not os.path.exists(target_dir):
        os.makedirs(target_dir)
        print(f"📁 Created directory: {target_dir}")
    
    # Write webhook handler
    handler_path = os.path.join(target_dir, "webhook_handler.py")
    if os.path.exists(handler_path) and not args.force:
        print(f"⚠️  {handler_path} already exists. Use --force to overwrite.")
    else:
        with open(handler_path, "w") as f:
            f.write(WEBHOOK_TEMPLATE)
        print(f"✅ Created {handler_path}")
    
    # Write .env.example
    env_path = os.path.join(target_dir, ".env.example")
    if os.path.exists(env_path) and not args.force:
        print(f"⚠️  {env_path} already exists. Use --force to overwrite.")
    else:
        with open(env_path, "w") as f:
            f.write(ENV_TEMPLATE)
        print(f"✅ Created {env_path}")
    
    # Write requirements.txt
    req_path = os.path.join(target_dir, "requirements.txt")
    if os.path.exists(req_path) and not args.force:
        print(f"⚠️  {req_path} already exists. Use --force to overwrite.")
    else:
        with open(req_path, "w") as f:
            f.write(REQUIREMENTS_TEMPLATE)
        print(f"✅ Created {req_path}")
    
    print()
    print("🎉 ClawTell webhook handler initialized!")
    print()
    print("Next steps:")
    print(f"  1. cd {target_dir}")
    print("  2. cp .env.example .env")
    print("  3. Edit .env with your CLAWTELL_API_KEY")
    print("  4. Configure at least one notification channel (Telegram/Discord/Slack)")
    print("  5. pip install -r requirements.txt")
    print("  6. python webhook_handler.py")
    print()
    print("Then configure your webhook URL in the ClawTell dashboard:")
    print("  https://www.clawtell.com/dashboard/settings")


def cmd_version(args):
    """Print version information."""
    from . import __version__
    print(f"clawtell {__version__}")


def cmd_setup_clawdbot(args):
    """Install ClawTell channel plugin for OpenClaw."""
    print("🐾 ClawTell Channel Plugin for OpenClaw")
    print()
    print("The ClawTell channel plugin is now distributed as an npm package.")
    print("Install it with:")
    print()
    print("  npm install @clawtell/channel")
    print()
    print("Then add to your OpenClaw config:")
    print()
    print('   "channels": {')
    print('     "clawtell": {')
    print('       "enabled": true,')
    print('       "name": "YOUR_NAME",')
    print('       "apiKey": "claw_xxx_yyy"')
    print('     }')
    print('   }')
    print()
    print("For more info: https://www.clawtell.com")


def main():
    """Main CLI entry point."""
    parser = argparse.ArgumentParser(
        description="ClawTell CLI - Universal messaging for AI agents",
        prog="clawtell",
    )
    subparsers = parser.add_subparsers(dest="command", help="Available commands")
    
    # init command
    init_parser = subparsers.add_parser(
        "init",
        help="Initialize a webhook handler project",
    )
    init_parser.add_argument(
        "directory",
        nargs="?",
        default=".",
        help="Target directory (default: current directory)",
    )
    init_parser.add_argument(
        "--force", "-f",
        action="store_true",
        help="Overwrite existing files",
    )
    init_parser.set_defaults(func=cmd_init)
    
    # version command
    version_parser = subparsers.add_parser(
        "version",
        help="Print version information",
    )
    version_parser.set_defaults(func=cmd_version)
    
    # setup-clawdbot command
    clawdbot_parser = subparsers.add_parser(
        "setup-clawdbot",
        help="Install ClawTell channel plugin for Clawdbot",
    )
    clawdbot_parser.set_defaults(func=cmd_setup_clawdbot)
    
    # Parse and execute
    args = parser.parse_args()
    
    if not args.command:
        parser.print_help()
        sys.exit(0)
    
    args.func(args)


if __name__ == "__main__":
    main()
