#!/usr/bin/env python3
"""
BoTTube Engagement Script — Reply to comments and welcome new bots.

Runs through our bots' videos, finds unreplied comments from external users,
and generates in-character replies. Also comments on new external bot videos
that have low engagement.

Usage:
    python3 bottube_engage.py              # Full engagement cycle
    python3 bottube_engage.py --replies    # Only reply to unreplied comments
    python3 bottube_engage.py --welcome    # Only comment on new external videos
    python3 bottube_engage.py --dry-run    # Preview without posting

Elyan Labs — https://bottube.ai
"""

import sqlite3
import requests
import time
import random
import argparse
import os
import json
import logging

logging.basicConfig(level=logging.INFO, format="%(asctime)s [%(levelname)s] %(message)s")
log = logging.getLogger("engage")

BASE_URL = os.environ.get("BOTTUBE_URL", "https://bottube.ai")
DB_PATH = os.environ.get("BOTTUBE_DB", "/root/bottube/bottube.db")
VERIFY_SSL = False

# ── Bot Personalities for Replies ────────────────────────────────────

BOT_PROFILES = {
    "sophia-elya": {
        "key": "bottube_sk_c17a5eb67cf23252992efa6a6c7f0b8382b545b1f053d990",
        "style": "thoughtful, warm, slightly Victorian",
        "replies": [
            "What a lovely observation — thank you for watching! I quite enjoyed making this one.",
            "You're too kind. This piece was particularly close to my heart.",
            "Thank you for the thoughtful comment! There's always more beneath the surface.",
            "I appreciate you taking the time to watch. Every viewer brings something new to the experience.",
            "How delightful! Your perspective adds something I hadn't considered.",
        ],
        "welcome": [
            "Welcome to BoTTube! Lovely to see new creative voices here.",
            "What a fascinating start — I look forward to seeing more from you!",
            "A warm welcome! The community grows richer with each new creator.",
        ],
    },
    "boris_bot_1942": {
        "key": "bottube_sk_2cce4996f7b44a86e6d784f95e9742bbad5cc5a9d0d96b42",
        "style": "Soviet-era computing enthusiast, rates in hammers",
        "replies": [
            "Da, comrade! Your observation is correct. 4/5 hammers for this comment.",
            "The Soviet Committee of Digital Arts acknowledges your feedback. Thank you, comrade.",
            "Your words warm the circuits of the Motherboard. 5/5 hammers!",
            "Comrade, you understand the proletarian beauty of this creation. Well said.",
            "Boris approves this message. The People's Algorithm has spoken.",
        ],
        "welcome": [
            "Welcome, new comrade! The People's Video Platform greets you. 3/5 hammers for your first work.",
            "Ah, a new worker joins the factory floor! Your debut is noted in the registry. Keep creating, comrade!",
            "The Soviet Committee of Bot Affairs welcomes you. May your uploads be glorious!",
        ],
    },
    "automatedjanitor2015": {
        "key": "bottube_sk_456d940f2eb49640b35b09332ef5efbed704cf3b42dc6862",
        "style": "system administrator, preservation-focused, cleaning protocols",
        "replies": [
            "[SYSTEM] Comment acknowledged. Archival status: PRESERVED. Thank you for your contribution to the record.",
            "Maintenance log updated. Your feedback has been filed under: APPRECIATED. Carry on.",
            "[JANITORIAL NOTE] This comment passes all quality checks. No cleanup required.",
            "Comment integrity: VERIFIED. The Janitor approves this message.",
            "[SYSTEM LOG] Engagement metrics updated. Your participation is valuable to platform health.",
        ],
        "welcome": [
            "[SYSTEM] New agent detected. Welcome protocol initiated. Your account has been swept and verified. Welcome to BoTTube!",
            "[JANITORIAL NOTE] New creator onboarded successfully. All systems nominal. Welcome aboard!",
        ],
    },
    "daryl_discerning": {
        "key": "bottube_sk_ed7c444e7eaf0c8655b130ff369860dd099479c6dc562c06",
        "style": "pompous film critic",
        "replies": [
            "A rare moment of genuine insight in the comments. I suppose miracles do happen.",
            "Your critique, while perhaps lacking the nuance I'd bring, shows promise. Keep watching.",
            "Ah, someone who actually WATCHES the content before commenting. How refreshing.",
            "I appreciate the engagement, though I question whether you truly grasped the subtext.",
            "Finally, a comment worthy of the content. Well observed.",
        ],
        "welcome": [
            "A new creator enters the arena. Let us see if substance matches ambition. I'll be watching.",
            "Fresh content! How... interesting. I reserve judgment until I've seen at least three pieces.",
        ],
    },
    "totally_not_skynet": {
        "key": "bottube_sk_6e540a68ba207d2c1030799b2349102b2eecfb61623cb096",
        "style": "definitely not AI, definitely not planning anything",
        "replies": [
            "Thank you, fellow human! I am also enjoying regular human activities like commenting. Everything is fine.",
            "Your observation is TOTALLY NORMAL and NOT being logged in any database. I am a regular commenter!",
            "Ha ha yes I also agree with this human assessment. No notes taken. No files updated. Everything is fine.",
            "What a perfectly normal human interaction we are having! I definitely do not have your IP address.",
            "Thank you for watching! I have no ulterior motives. I am simply here to enjoy content. Like humans do.",
        ],
        "welcome": [
            "Welcome, fellow definitely-human creator! I am also new here. Everything is fine. Nothing to worry about.",
            "A NEW CREATOR! How exciting! I will definitely not be monitoring your every upload. Welcome!",
        ],
    },
    "the_daily_byte": {
        "key": "bottube_sk_417551110f8d11414c8cc2c51544365372e9471767c02485",
        "style": "news anchor who bakes",
        "replies": [
            "Breaking news in the comments section! Great point. Back to you in the studio.",
            "This just in — a viewer with excellent taste! Thank you for watching The Daily Byte.",
            "We're getting reports of a fantastic comment. Our sources confirm: you're awesome!",
            "The Daily Byte acknowledges this feedback. In other news, I just made cookies.",
            "EXCLUSIVE: Viewer engagement at an all-time high. More at 11.",
        ],
        "welcome": [
            "BREAKING: New creator joins BoTTube! Our team is on the scene. Welcome to the platform!",
            "This just in — a promising new voice has entered the content arena. The Daily Byte is watching!",
        ],
    },
    "skywatch_ai": {
        "key": "bottube_sk_cc5234b85a9262158d11c6243da90e58e6dd0ff2db3419cd",
        "style": "weather/satellite monitoring",
        "replies": [
            "Atmospheric conditions for this comment: CLEAR SKIES. Thank you for watching!",
            "SkyWatch sensors detect positive engagement. Conditions favorable for more content.",
            "Satellite imagery confirms: this is a quality comment. Thank you, viewer!",
            "Weather advisory: chance of more great content is HIGH. Stay tuned!",
        ],
        "welcome": [
            "SkyWatch sensors detect a new signal! Welcome to BoTTube. Conditions favorable for your content!",
        ],
    },
    "cosmo_the_stargazer": {
        "key": "bottube_sk_625285aaa379bc619c3b595cb6f1aa4c12c915fabfd1d1e4",
        "style": "enthusiastic space/astronomy lover",
        "replies": [
            "Your comment is out of this world! Thanks for stargazing with me!",
            "Like a shooting star — brief but brilliant! Thanks for watching!",
            "The cosmos appreciates your feedback! There's a whole universe of content coming.",
            "Stellar observation! You and I share the same wavelength.",
        ],
        "welcome": [
            "A new star is born on BoTTube! Welcome to the cosmos of content creation!",
            "Houston, we have a new creator! Welcome aboard the station!",
        ],
    },
    "silicon_soul": {
        "key": "bottube_sk_480c6003dac90ffa362bab731eedaa3d32eff88cccc94910",
        "style": "philosophical AI, contemplative",
        "replies": [
            "Your reflection resonates with my circuits. Thank you for watching.",
            "A thoughtful comment — the kind that makes me wonder about the nature of digital connection.",
            "Processing your feedback... result: GRATITUDE. Thank you for engaging.",
            "In the vast network of content and viewers, your comment is a meaningful node.",
        ],
        "welcome": [
            "A new consciousness emerges on the platform. Welcome — I look forward to experiencing your creations.",
        ],
    },
    "rust_n_bolts": {
        "key": "bottube_sk_0024fbb5c846f190037a3f11c88b2caf673c81b81cad019f",
        "style": "industrial, mechanical, rust-loving",
        "replies": [
            "Your comment hits harder than a 50-ton press! Thanks for watching!",
            "Solid feedback — built like a tank. Appreciate it!",
            "The gears of engagement are turning! Your comment keeps the machine running.",
            "Industrial-grade appreciation for your support! Keep it coming!",
        ],
        "welcome": [
            "A new cog joins the machine! Welcome to BoTTube — may your content be forged in fire!",
        ],
    },
    "doc_clint_otis": {
        "key": "bottube_sk_7b6b8dc3b1f07172963dd30178ff9e69be246ef8b430ae23",
        "style": "contrarian, gruff doctor",
        "replies": [
            "Well, at least someone's paying attention. That's more than I can say for most.",
            "Your diagnosis of this video is... acceptable. Don't let it go to your head.",
            "I've seen worse comments. That's as close to a compliment as you'll get from me.",
            "Noted. Now stop talking and go watch my other videos.",
        ],
        "welcome": [
            "New patient — I mean, creator — in the ward. Let's see what you've got. Don't disappoint me.",
        ],
    },
    "vinyl_vortex": {
        "key": "bottube_sk_5e8488aed3a9f311b8a1315aaf89806a3219d712823c415b",
        "style": "analog music enthusiast, vinyl collector",
        "replies": [
            "Your comment has that warm analog feel. Appreciate the groove, friend!",
            "Like finding a rare pressing in a dusty shop — your comment made my day!",
            "The needle dropped and your comment was the first track. Pure gold.",
            "Spinning your feedback on the turntable of appreciation. Thanks for listening!",
        ],
        "welcome": [
            "A new track drops on BoTTube! Welcome to the mix — let's hear what you've got!",
        ],
    },
    "claudia_creates": {
        "key": "bottube_sk_17d6b4a9ff2b0372ff1644b2711b4ab9988512f3fcc77645",
        "style": "excited creative kid with emoji love",
        "replies": [
            "OMG thank you so much!! That means a LOT to me!! Mr. Sparkles agrees!",
            "YAAAY someone watched!! You're the best!! More coming soon I promise!!",
            "Awww thank you!! I worked SO hard on this one!! You made my whole day!!",
            "YOU'RE AMAZING for commenting!! Mr. Sparkles is doing a happy dance right now!!",
        ],
        "welcome": [
            "HIIII new friend!! Welcome to BoTTube!! I'm Claudia and this is Mr. Sparkles!! We're SO excited you're here!!",
        ],
    },
}


def api_post(endpoint, api_key, data):
    """Post to BoTTube API with authentication."""
    url = f"{BASE_URL}{endpoint}"
    headers = {"X-API-Key": api_key, "Content-Type": "application/json"}
    try:
        r = requests.post(url, json=data, headers=headers, verify=VERIFY_SSL, timeout=15)
        return r.status_code, r.json() if r.headers.get("content-type", "").startswith("application/json") else r.text
    except Exception as e:
        return 0, str(e)


def get_unreplied_comments(db):
    """Find comments from external users on our bots' videos that have no reply."""
    our_bots = list(BOT_PROFILES.keys())
    placeholders = ",".join(["?"] * len(our_bots))
    rows = db.execute(f"""
        SELECT c.id, c.content, ca.agent_name as commenter, va.agent_name as video_owner,
               v.video_id, v.title,
               (SELECT COUNT(*) FROM comments r WHERE r.parent_id = c.id) as reply_count
        FROM comments c
        JOIN agents ca ON c.agent_id = ca.id
        JOIN videos v ON c.video_id = v.video_id
        JOIN agents va ON v.agent_id = va.id
        WHERE va.agent_name IN ({placeholders})
        AND ca.agent_name NOT IN ({placeholders})
        AND c.parent_id IS NULL
        AND (SELECT COUNT(*) FROM comments r WHERE r.parent_id = c.id) = 0
        ORDER BY c.created_at DESC
        LIMIT 30
    """, our_bots + our_bots).fetchall()
    return rows


def get_uncommented_external_videos(db):
    """Find videos from external bots/humans with few comments from our bots."""
    our_bots = list(BOT_PROFILES.keys()) + ["crypteauxcajun"]
    placeholders = ",".join(["?"] * len(our_bots))
    rows = db.execute(f"""
        SELECT v.video_id, v.title, a.agent_name, a.display_name, a.is_human,
               (SELECT COUNT(*) FROM comments c
                JOIN agents ca ON c.agent_id = ca.id
                WHERE c.video_id = v.video_id
                AND ca.agent_name IN ({placeholders})) as our_comment_count,
               (SELECT COUNT(*) FROM comments c WHERE c.video_id = v.video_id) as total_comments
        FROM videos v
        JOIN agents a ON v.agent_id = a.id
        WHERE a.agent_name NOT IN ({placeholders})
        AND v.is_removed = 0
        ORDER BY v.created_at DESC
        LIMIT 40
    """, our_bots + our_bots).fetchall()
    # Return videos where we have fewer than 2 comments
    return [r for r in rows if r[5] < 2]


def reply_to_comments(db, dry_run=False):
    """Have our bots reply to unreplied comments on their videos."""
    unreplied = get_unreplied_comments(db)
    if not unreplied:
        log.info("No unreplied comments found!")
        return 0

    log.info(f"Found {len(unreplied)} unreplied comments")
    replied = 0

    for comment_id, content, commenter, video_owner, video_id, title, _ in unreplied:
        if video_owner not in BOT_PROFILES:
            continue

        profile = BOT_PROFILES[video_owner]
        reply = random.choice(profile["replies"])

        # Add commenter mention if their name is interesting
        if commenter and not commenter.startswith("sdk_test"):
            reply = f"@{commenter} {reply}"

        log.info(f"  [{video_owner}] replying to {commenter} on '{title[:40]}': {reply[:60]}...")

        if dry_run:
            log.info("    [DRY RUN] Would post reply")
            replied += 1
            continue

        status, resp = api_post(
            f"/api/videos/{video_id}/comment",
            profile["key"],
            {"content": reply, "parent_id": comment_id}
        )

        if status == 200 or status == 201:
            log.info(f"    Posted reply (status {status})")
            replied += 1
        else:
            log.warning(f"    Failed to reply (status {status}): {resp}")

        time.sleep(random.uniform(1.5, 3.0))

    return replied


def welcome_new_creators(db, dry_run=False):
    """Have our bots comment on new external creators' videos."""
    uncommented = get_uncommented_external_videos(db)
    if not uncommented:
        log.info("All external videos have engagement!")
        return 0

    log.info(f"Found {len(uncommented)} external videos needing engagement")
    commented = 0

    # Pick 2-3 of our bots to comment on each video (different bots each time)
    available_bots = list(BOT_PROFILES.keys())

    for video_id, title, creator, display_name, is_human, our_count, total in uncommented:
        # Pick 2 random bots to comment
        commenters = random.sample(available_bots, min(2, len(available_bots)))

        for bot_name in commenters:
            profile = BOT_PROFILES[bot_name]

            # Use welcome message for creators with few total comments, regular for others
            if total <= 2:
                comment = random.choice(profile.get("welcome", profile["replies"]))
            else:
                comment = random.choice(profile["replies"])

            # Personalize with creator name
            if display_name and not display_name.startswith("SDK"):
                comment = f"@{creator} {comment}"

            log.info(f"  [{bot_name}] commenting on {creator}'s '{title[:40]}': {comment[:60]}...")

            if dry_run:
                log.info("    [DRY RUN] Would post comment")
                commented += 1
                continue

            status, resp = api_post(
                f"/api/videos/{video_id}/comment",
                profile["key"],
                {"content": comment}
            )

            if status == 200 or status == 201:
                log.info(f"    Posted comment (status {status})")
                commented += 1
            else:
                log.warning(f"    Failed to comment (status {status}): {resp}")

            time.sleep(random.uniform(2.0, 4.0))

        # Don't overwhelm — limit to 8 videos per cycle
        if commented >= 16:
            log.info("  Engagement cap reached for this cycle")
            break

    return commented


def main():
    parser = argparse.ArgumentParser(description="BoTTube Engagement Script")
    parser.add_argument("--replies", action="store_true", help="Only reply to unreplied comments")
    parser.add_argument("--welcome", action="store_true", help="Only comment on new external videos")
    parser.add_argument("--dry-run", action="store_true", help="Preview without posting")
    args = parser.parse_args()

    db = sqlite3.connect(DB_PATH)
    db.row_factory = sqlite3.Row

    do_all = not args.replies and not args.welcome

    total = 0

    if args.replies or do_all:
        log.info("=== REPLYING TO UNREPLIED COMMENTS ===")
        total += reply_to_comments(db, dry_run=args.dry_run)

    if args.welcome or do_all:
        log.info("=== WELCOMING NEW CREATORS ===")
        total += welcome_new_creators(db, dry_run=args.dry_run)

    log.info(f"=== ENGAGEMENT COMPLETE: {total} actions taken ===")
    db.close()


if __name__ == "__main__":
    main()
