#!/usr/bin/env python3
"""Append 🎬 Top 5 Video Opportunities to Reddit gaps reports.

Scores each gap post by engagement + vertical relevance + visual potential,
then appends a markdown table section matching the banger-x video opportunity format.
"""

import re
import json
import os
import sys
from datetime import datetime
from pathlib import Path

# Vertical relevance scoring — which subreddits map to product opportunities
VERTICAL_WEIGHTS = {
    # Sleep / Nestra
    "sleep":        {"weight": 1.5, "vertical": "sleep", "product": "NestraSleep"},
    "insomnia":     {"weight": 1.5, "vertical": "sleep", "product": "NestraSleep"},
    # Posture / NeckLog+
    "posture":      {"weight": 1.5, "vertical": "posture", "product": "NeckLog+"},
    "backpain":     {"weight": 1.4, "vertical": "posture", "product": "NeckLog+"},
    "tmj":          {"weight": 1.3, "vertical": "posture", "product": "NeckLog+"},
    "chronicpain":  {"weight": 1.3, "vertical": "posture", "product": "NeckLog+"},
    "migraine":     {"weight": 1.2, "vertical": "posture", "product": "NeckLog+"},
    "fibromyalgia": {"weight": 1.2, "vertical": "posture", "product": "NeckLog+"},
    "hermesagent":  {"weight": 1.4, "vertical": "ai-tools", "product": "Hermes Agent"},
    "stableDiffusion": {"weight": 1.3, "vertical": "ai-tools", "product": "AI video"},
    "generativeAI": {"weight": 1.3, "vertical": "ai-tools", "product": "AI video"},
    "vibecoding":   {"weight": 1.2, "vertical": "ai-tools", "product": "AI coding"},
    # Ecom / general high-interest
    "frugal":       {"weight": 1.1, "vertical": "ecom", "product": "general"},
    "digitalnomad": {"weight": 1.1, "vertical": "ecom", "product": "general"},
    # Medium interest
    "adhdwomen":    {"weight": 1.0, "vertical": "lifestyle", "product": "general"},
    "socialskills": {"weight": 0.9, "vertical": "lifestyle", "product": "general"},
    "decidingtobebetter": {"weight": 0.9, "vertical": "lifestyle", "product": "general"},
    "confidence":   {"weight": 0.9, "vertical": "lifestyle", "product": "general"},
    "roadtrip":     {"weight": 0.8, "vertical": "travel", "product": "general"},
    "onebag":       {"weight": 0.8, "vertical": "travel", "product": "general"},
    "technology":   {"weight": 0.7, "vertical": "tech", "product": "general"},
    "pcmasterrace": {"weight": 0.7, "vertical": "tech", "product": "general"},
    "askreddit":    {"weight": 0.6, "vertical": "general", "product": "general"},
    "xxfitness":    {"weight": 0.9, "vertical": "fitness", "product": "general"},
}

# Patterns that suggest a post is visually demonstrable (good for video reply)
VISUAL_PATTERNS = [
    r"how.*fix", r"how.*relieve", r"how.*stop", r"how.*improve",
    r"any.*exercis", r"stretch", r"routine", r"technique",
    r"guide", r"tutorial", r"demonstrat", r"show me",
    r"pain in.*sleep", r"posture", r"alignment",
    r"before.*after", r"transform",
]

def extract_subreddit_posts(content):
    """Parse gaps report markdown, extract (subreddit, posts) pairs."""
    sections = []
    current_sub = None
    current_posts = []

    for line in content.split("\n"):
        m = re.match(r"^## r/(\w+)", line)
        if m:
            if current_sub and current_posts:
                sections.append((current_sub, current_posts))
            current_sub = m.group(1)
            current_posts = []
            continue

        if current_sub:
            # Match a post entry
            pm = re.match(r"\*\*\[(.+?)\]\((.+?)\)\*\*", line)
            if pm:
                current_posts.append({
                    "title": pm.group(1),
                    "url": pm.group(2),
                    "line": line,
                })

            # Match engagement: ⬆️ X | 💬 Y
            em = re.search(r"⬆️\s*([\d,]+)\s*\|\s*💬\s*([\d,]+)", line)
            if em and current_posts:
                current_posts[-1]["upvotes"] = int(em.group(1).replace(",", ""))
                current_posts[-1]["comments"] = int(em.group(2).replace(",", ""))

            # Match patterns line
            pm2 = re.match(r"¹\s*(Score|Patterns):", line)
            if pm2 and current_posts:
                if "patterns" not in current_posts[-1]:
                    current_posts[-1]["patterns"] = line.split("Patterns:")[-1].strip() if "Patterns:" in line else ""

    if current_sub and current_posts:
        sections.append((current_sub, current_posts))

    return sections

def score_post(post, subreddit):
    """Score a post for video opportunity potential.

    Engagement is the primary driver — vertical relevance and visual
    potential are secondary tiebreakers. Prevents low-engagement niche
    posts from outranking high-engagement general ones.
    """
    upvotes = post.get("upvotes", 0)
    comments = post.get("comments", 0)
    title = post.get("title", "").lower()

    # Base engagement — linear so high-engagement posts actually dominate
    engagement_raw = upvotes + comments * 1.5
    engagement = engagement_raw ** 0.75 if engagement_raw > 0 else 0

    # Vertical relevance (smaller range: 1.0–1.4 instead of 0.5–1.5)
    sub_key = subreddit.lower()
    vert_info = VERTICAL_WEIGHTS.get(sub_key, {"weight": 0.5, "vertical": "other", "product": "general"})
    raw_weight = vert_info["weight"]
    vert_bonus = 1.0 + (raw_weight * 0.3)  # maps 1.5 -> 1.45, 0.5 -> 1.15

    # Visual demonstrability bonus
    visual_bonus = 1.0
    for pat in VISUAL_PATTERNS:
        if re.search(pat, title):
            visual_bonus = 1.2
            break

    # Question / intent bonus
    question_bonus = 1.15 if "?" in title else 1.0
    how_bonus = 1.2 if any(w in title for w in ["how ", "what ", "why ", "any ", "tips "]) else 1.0

    # Comment density bonus — threads with many comments relative to
    # upvotes indicate active discussion (good for reply visibility)
    comment_density = 1.0
    if upvotes > 0 and comments / max(upvotes, 1) > 1.5:
        comment_density = 1.2

    score = engagement * vert_bonus * visual_bonus * question_bonus * how_bonus * comment_density
    return round(score, 1), vert_info

# Hook templates indexed by (vertical, pattern_match). Each entry is a list
# so we can rotate and avoid repeating the same hook across posts.
HOOK_TEMPLATES = {
    "sleep": [
        "I tried everything for insomnia — this 60-second routine actually worked",
        "The sleep mistake that's keeping you awake (and how to fix it tonight)",
        "Why your sleep quality is terrible — and the one thing that changed it",
        "Sleep anxiety loop? Here's how to break it without meds",
        "The 3-minute wind-down that replaced my sleep meds",
        "Doctors won't tell you this about chronic insomnia",
        "How I finally stopped waking up at 3am — no pills needed",
    ],
    "posture": [
        "That neck hump isn't permanent — here's what actually works",
        "TMJ relief in under 60 seconds — the jaw trick nobody talks about",
        "Stop chasing pain relief — fix the root cause in your sleep",
        "Your posture is the problem nobody diagnoses — here's the real fix",
        "The 2-minute stretch that fixed my chronic back pain",
        "Why your neck pain keeps coming back (and how to stop it)",
        "This posture fix took me 30 seconds — changed everything",
        "The hidden cause of daily headaches that physios miss",
    ],
    "ai-tools": [
        "Hermes Agent vs Claude Code — the honest comparison nobody's posting",
        "Everyone's making AI video wrong — here's the $0.05/gen pipeline",
        "The tool stack nobody's talking about — 10x your workflow",
        "I tested every AI coding tool this month — here's the winner",
        "Why most people waste money on AI tools (and what to use instead)",
        "The free AI tool that replaced my $50/mo subscription",
    ],
    "general": [
        "The thing nobody tells you about {topic}",
        "I spent weeks researching {topic} — here's what actually works",
        "Why everyone gets {topic} wrong (and the simple fix)",
        "The {topic} hack that saved me hours every week",
        "Stop doing {topic} the hard way — here's the shortcut",
    ],
}

def _extract_topic(title):
    """Extract a clean 2-5 word topic from a post title for hook templates."""
    # Strip common prefixes
    t = title.lower()
    for prefix in ["i ", "my ", "the ", "a ", "an ", "is ", "are ", "was ", "were ", "do ", "does ", "did ", "will ", "would ", "could ", "should ", "can ", "cannot ", "can't ", "don't ", "doesn't ", "didn't ", "won't ", "wouldn't ", "couldn't ", "shouldn't "]:
        if t.startswith(prefix):
            t = t[len(prefix):]
            break
    # Strip question suffixes
    for suffix in ["?", ".", "!", "help", "advice", "thoughts", "opinions", "suggestions", "tips"]:
        if t.endswith(" " + suffix):
            t = t[:-(len(suffix) + 1)]
    # Strip common lead-ins
    for lead in ["what finally made you ", "what made you ", "how do you ", "how to ", "why is ", "why are ", "why do ", "why does ", "what is ", "what are ", "what do ", "what does ", "for those who ", "for people who ", "suggestion on ", "advice for ", "help with ", "question about "]:
        if t.startswith(lead):
            t = t[len(lead):]
            break
    # Truncate to 5 words max
    words = t.split()[:5]
    return " ".join(words) if words else "this"

def _pick_hook(templates, index, **kwargs):
    """Pick a hook from templates, rotating by index to avoid repeats."""
    if not templates:
        return "Here's what actually works"
    return templates[index % len(templates)].format(**kwargs)

def generate_hook(post, subreddit, vert_info, rank):
    """Generate a punchy video hook based on post content.

    Uses rank as rotation index so consecutive posts get different hooks.
    """
    title = post.get("title", "")
    vertical = vert_info.get("vertical", "general")
    product = vert_info.get("product", "")
    title_lower = title.lower()

    if vertical == "sleep":
        return _pick_hook(HOOK_TEMPLATES["sleep"], rank)
    elif vertical == "posture":
        if "neck" in title_lower or "hump" in title_lower:
            return _pick_hook(HOOK_TEMPLATES["posture"][:3], rank)
        elif "jaw" in title_lower or "tmj" in title_lower:
            return _pick_hook(HOOK_TEMPLATES["posture"][1:3], rank)
        elif "pain" in title_lower:
            return _pick_hook(HOOK_TEMPLATES["posture"][2:5], rank)
        return _pick_hook(HOOK_TEMPLATES["posture"], rank + 3)
    elif vertical == "ai-tools":
        if "hermes" in title_lower or "agent" in title_lower:
            return _pick_hook(HOOK_TEMPLATES["ai-tools"][:2], rank)
        elif "video" in title_lower or "anime" in title_lower:
            return _pick_hook(HOOK_TEMPLATES["ai-tools"][1:3], rank)
        return _pick_hook(HOOK_TEMPLATES["ai-tools"], rank + 2)
    elif product and product != "general":
        return f"{product} solves this — here's how in 60 seconds"
    else:
        topic = _extract_topic(title)
        return _pick_hook(HOOK_TEMPLATES["general"], rank, topic=topic)

def generate_why_video(post, subreddit, vert_info):
    """Explain why this post is a strong video opportunity."""
    upvotes = post.get("upvotes", 0)
    comments = post.get("comments", 0)
    vertical = vert_info.get("vertical", "general")
    product = vert_info.get("product", "general")

    reasons = []

    if upvotes > 50:
        reasons.append(f"🔸 {upvotes} upvotes — proven demand")
    elif upvotes > 10:
        reasons.append(f"📈 {upvotes} upvotes — growing interest")
    elif upvotes > 0:
        reasons.append(f"⬆️ {upvotes} upvotes")

    if comments >= 20:
        reasons.append(f"💬 {comments} comments — active thread, reply still visible")
    elif comments > 0:
        reasons.append(f"💬 {comments} replies — low competition for reply visibility")
    else:
        reasons.append("New thread — zero replies, first-mover advantage")

    if product != "general":
        reasons.append(f"🎯 Direct {product} product fit")
    if vertical in ("sleep", "posture"):
        reasons.append("📹 Visually demonstrable — perfect for short video")
    if vertical == "ai-tools":
        reasons.append("🛠️ Tool demo opportunity — show vs. tell")

    return " · ".join(reasons)


def generate_brief(post, subreddit, vert_info):
    """Generate a short production brief for the video.

    Returns a concise string: angle, visual approach, and CTA suggestion.
    """
    title = post.get("title", "")
    vertical = vert_info.get("vertical", "general")
    product = vert_info.get("product", "general")
    title_lower = title.lower()

    # Determine the angle
    if "how" in title_lower or "tips" in title_lower or "guide" in title_lower:
        angle = "How-to / tutorial"
    elif "why" in title_lower or "what" in title_lower:
        angle = "Explainer / myth-bust"
    elif "struggl" in title_lower or "pain" in title_lower or "anxiety" in title_lower:
        angle = "Empathy → solution"
    elif "recommend" in title_lower or "suggestion" in title_lower:
        angle = "Recommendation / comparison"
    else:
        angle = "Story → insight"

    # Visual approach
    if vertical == "posture":
        visual = "B-roll: posture demo, before/after overlay, text callouts"
    elif vertical == "sleep":
        visual = "B-roll: bedroom setup, sleep tracking visuals, calming overlay"
    elif vertical == "ai-tools":
        visual = "Screen recording + face cam, tool UI walkthrough"
    else:
        visual = "Face cam + text overlay, B-roll as needed"

    # CTA
    if product == "NestraSleep":
        cta = "CTA: 'Link in bio for the sleep routine'"
    elif product == "NeckLog+":
        cta = "CTA: 'Try the free posture assessment — link in bio'"
    elif product and product != "general":
        cta = f"CTA: 'Check out {product} — link in bio'"
    else:
        cta = "CTA: 'Follow for more' or soft product mention"

    return f"{angle} | {visual} | {cta}"

def process_file(filepath):
    """Process a single gaps report and append the Top 5 Video Opportunities section."""
    with open(filepath) as f:
        content = f.read()

    # Check if already has the section
    if "🎬 Top 5 Video Opportunities" in content or "Top 5 Video" in content:
        print(f"  ⏭️  Already has video opportunities section — skipping")
        return False

    sections = extract_subreddit_posts(content)
    if not sections:
        print(f"  ⚠️  No subreddit sections found")
        return False

    # Score all posts
    scored = []
    for subreddit, posts in sections:
        for post in posts:
            score, vert_info = score_post(post, subreddit)
            scored.append((score, subreddit, post, vert_info))

    # Sort by score descending
    scored.sort(key=lambda x: x[0], reverse=True)

    # Take top 5
    top5 = scored[:5]

    if not top5:
        print(f"  ⚠️  No posts to score")
        return False

    # Build the section
    generated = datetime.now().strftime("%Y-%m-%d %H:%M")
    lines = []
    lines.append(f"\n---\n")
    lines.append(f"\n## 🎬 Top 5 Video Opportunities")
    lines.append(f"\n**Auto-generated:** {generated}  ")
    lines.append(f"**Source:** Gap post analysis — ranked by engagement × vertical relevance × visual potential  ")
    lines.append(f"\n| Rank | Subreddit | Post Title | Engagement | Why It's a Video Pick | Hook | Brief |")
    lines.append(f"|------|-----------|-----------|------------|----------------------|------|-------|")

    for i, (score, subreddit, post, vert_info) in enumerate(top5, 1):
        title = post.get("title", "Untitled")
        upvotes = post.get("upvotes", 0)
        comments = post.get("comments", 0)
        url = post.get("url", "#")

        # Escape pipe characters in title
        safe_title = title.replace("|", "\\|").replace("\n", " ").strip()
        # Truncate long titles
        if len(safe_title) > 80:
            safe_title = safe_title[:77] + "..."

        engagement_str = f"⬆️ {upvotes} | 💬 {comments}"
        why = generate_why_video(post, subreddit, vert_info)
        hook = generate_hook(post, subreddit, vert_info, rank=i)
        brief = generate_brief(post, subreddit, vert_info)

        lines.append(f"| {i} | r/{subreddit} | [{safe_title}]({url}) | {engagement_str} | {why} | {hook} | {brief} |")

    lines.append("")

    # ---- New: Top 5 by Comments ----
    # Sort all scored posts by comment count descending
    by_comments = sorted(scored, key=lambda x: x[2].get("comments", 0), reverse=True)
    # Filter out posts with 0 comments
    by_comments = [x for x in by_comments if x[2].get("comments", 0) > 0]
    top5_comments = by_comments[:5]

    if top5_comments:
        lines.append(f"\n### 💬 Top 5 by Comment Activity")
        lines.append(f"\n**Auto-generated:** {generated}  ")
        lines.append(f"**Source:** Gap posts ranked by pure comment count — indicates active discussion & engagement  ")
        lines.append(f"\n| Rank | Subreddit | Post Title | Comments | Why It's Active | Hook | Brief |")
        lines.append(f"|------|-----------|-----------|----------|-----------------|------|-------|")

        for i, (score, subreddit, post, vert_info) in enumerate(top5_comments, 1):
            title = post.get("title", "Untitled")
            comments = post.get("comments", 0)
            upvotes = post.get("upvotes", 0)
            url = post.get("url", "#")

            safe_title = title.replace("|", "\\|").replace("\n", " ").strip()
            if len(safe_title) > 80:
                safe_title = safe_title[:77] + "..."

            # Why it's active
            reasons = []
            if comments >= 50:
                reasons.append(f"💥 {comments} comments — hot thread")
            elif comments >= 20:
                reasons.append(f"💬 {comments} comments — active debate")
            else:
                reasons.append(f"💬 {comments} comments — discussion growing")

            if upvotes > 50:
                reasons.append(f"⬆️ {upvotes} upvotes — high visibility")
            elif upvotes > 10:
                reasons.append(f"⬆️ {upvotes} upvotes")

            vertical = vert_info.get("vertical", "general")
            product = vert_info.get("product", "general")
            if product != "general":
                reasons.append(f"🎯 {product} opportunity")
            if vertical in ("sleep", "posture"):
                reasons.append("📹 Video-reply ready")

            why_active = " · ".join(reasons)
            hook = generate_hook(post, subreddit, vert_info, rank=i + 10)
            brief = generate_brief(post, subreddit, vert_info)

            lines.append(f"| {i} | r/{subreddit} | [{safe_title}]({url}) | 💬 {comments} | {why_active} | {hook} | {brief} |")

        lines.append("")
    # ---- End Top 5 by Comments ----

    section_text = "\n".join(lines)

    # Append to file
    with open(filepath, "a") as f:
        f.write(section_text)

    print(f"  ✅ Appended top {len(top5)} video opportunities")
    return True

def main():
    files = sys.argv[1:] if len(sys.argv) > 1 else []
    if not files:
        print("Usage: python3 append_video_opps.py <gaps_report_1.md> [gaps_report_2.md ...]")
        sys.exit(1)

    for fp in files:
        path = Path(fp)
        if not path.exists():
            print(f"  ❌ Not found: {fp}")
            continue
        print(f"📄 {path.name}...")
        process_file(str(path))

if __name__ == "__main__":
    main()
