#!/usr/bin/env python3
"""
Select 10 diverse clusters for Round 2 testing.

Criteria:
- 4 from body_is_weird
- 3 from power_works
- 3 from what_actually_happened

Mix:
- At least 3 clusters that produced BLAND titles (high score but generic)
- At least 3 clusters that produced DECENT titles
- At least 2 smaller clusters (under 20 posts)
"""

import json
import os

SANDBOX_DIR = os.path.dirname(os.path.abspath(__file__))
OUTPUT_DIR = os.path.join(os.path.dirname(SANDBOX_DIR), 'output')

# Markers of generic titles
GENERIC_MARKERS = [
    "Here's ", "How to ", "A Framework", "Decision Tree",
    "What You Need", "Everything You", "A Guide",
    "5 ", "7 ", "10 ", " Steps", " Ways to"
]

def is_generic_title(title):
    """Check if a title is generic/theme-based."""
    title_str = str(title)
    return any(m in title_str for m in GENERIC_MARKERS)

def load_channel_data(channel_id):
    """Load cluster data and opportunities for a channel."""
    # Load clusters
    cluster_path = os.path.join(SANDBOX_DIR, f'{channel_id}_clusters.json')
    with open(cluster_path) as f:
        cluster_data = json.load(f)

    # Load opportunities (existing pipeline output)
    opp_path = os.path.join(OUTPUT_DIR, f'analysis_opportunities_{channel_id}.json')
    try:
        with open(opp_path) as f:
            opp_data = json.load(f)
        opportunities = {o.get('cluster_id'): o for o in opp_data.get('opportunities', [])}
    except FileNotFoundError:
        opportunities = {}

    return cluster_data, opportunities

def analyze_cluster(cluster, opportunity=None):
    """Analyze a cluster for selection criteria."""
    topics = cluster.get('topics', [])
    posts = cluster.get('reddit_posts', [])
    cluster_id = cluster.get('cluster_id')
    topic_count = cluster.get('topic_count', len(topics))

    # Count posts with substantial selftext
    posts_with_content = sum(1 for p in posts if len(p.get('selftext', '')) > 100)

    # Get unique subreddits
    subreddits = list(set(p.get('subreddit', '') for p in posts))[:5]

    # Get sample topics
    sample_topics = [t.get('topic_name', '')[:50] for t in topics[:3]]

    result = {
        'cluster_id': cluster_id,
        'topic_count': topic_count,
        'post_count': len(posts),
        'posts_with_content': posts_with_content,
        'subreddits': subreddits,
        'sample_topics': sample_topics,
        '_cluster': cluster  # Keep reference for extraction
    }

    # Add pipeline output info if available
    if opportunity:
        title = opportunity.get('suggested_title', '')
        score = opportunity.get('weighted_score', 0)
        verdict = opportunity.get('verdict', '')

        result['pipeline_title'] = str(title)[:80]
        result['pipeline_score'] = score
        result['pipeline_verdict'] = verdict
        result['is_generic'] = is_generic_title(title)

    return result

def select_clusters_for_channel(channel_id, count, clusters, opportunities,
                                 need_generic=0, need_decent=0, need_small=0):
    """Select diverse clusters from a channel."""
    # Analyze all clusters
    analyzed = []
    for cluster in clusters:
        cluster_id = cluster.get('cluster_id')
        opp = opportunities.get(cluster_id)
        if opp:  # Only consider clusters that have pipeline output
            analysis = analyze_cluster(cluster, opp)
            if analysis['posts_with_content'] >= 3:  # Minimum content threshold
                analyzed.append(analysis)

    # Sort by pipeline score (we want interesting clusters)
    analyzed.sort(key=lambda x: x.get('pipeline_score', 0), reverse=True)

    print(f"\n{channel_id}: {len(analyzed)} clusters with pipeline output and content")

    # Categorize
    generic = [c for c in analyzed if c.get('is_generic', False)]
    decent = [c for c in analyzed if not c.get('is_generic', True)]
    small = [c for c in analyzed if c['topic_count'] < 20]

    print(f"  Generic titles: {len(generic)}, Decent titles: {len(decent)}, Small clusters: {len(small)}")

    # Select with diversity
    selected = []
    seen_ids = set()

    # First, get required generic titles
    for c in generic[:need_generic]:
        if c['cluster_id'] not in seen_ids:
            selected.append(c)
            seen_ids.add(c['cluster_id'])

    # Then, get required decent titles
    for c in decent[:need_decent]:
        if c['cluster_id'] not in seen_ids:
            selected.append(c)
            seen_ids.add(c['cluster_id'])

    # Then, prioritize small clusters if needed
    for c in small[:need_small]:
        if c['cluster_id'] not in seen_ids:
            selected.append(c)
            seen_ids.add(c['cluster_id'])

    # Fill remaining slots with highest scored
    for c in analyzed:
        if len(selected) >= count:
            break
        if c['cluster_id'] not in seen_ids:
            selected.append(c)
            seen_ids.add(c['cluster_id'])

    return selected[:count]

def extract_test_data(selected_clusters, channel_id):
    """Extract full test data for selected clusters."""
    test_data = []

    for i, metrics in enumerate(selected_clusters):
        cluster = metrics['_cluster']

        # Get all raw posts with their full content
        raw_posts = []
        for post in cluster.get('reddit_posts', []):
            raw_posts.append({
                'title': post.get('title', ''),
                'selftext': post.get('selftext', ''),
                'subreddit': post.get('subreddit', ''),
                'num_comments': post.get('num_comments', 0),
                'score': post.get('score', 0),
                'url': post.get('url', '')
            })

        # Get topics
        topics = []
        for t in cluster.get('topics', []):
            topics.append({
                'topic_name': t.get('topic_name', ''),
                'source': t.get('source', ''),
                'subreddit': t.get('subreddit', '')
            })

        test_cluster = {
            'test_id': f"{channel_id}_cluster_{i+1}",
            'cluster_id': metrics['cluster_id'],
            'channel': channel_id,
            'topic_count': metrics['topic_count'],
            'posts_with_content': metrics['posts_with_content'],
            'sample_topics': metrics['sample_topics'],
            'subreddits': metrics['subreddits'],
            # Pipeline output for comparison
            'pipeline_title': metrics.get('pipeline_title', 'N/A'),
            'pipeline_score': metrics.get('pipeline_score', 0),
            'pipeline_verdict': metrics.get('pipeline_verdict', 'N/A'),
            'is_generic_baseline': metrics.get('is_generic', False),
            # Raw data
            'topics': topics,
            'raw_posts': raw_posts
        }

        test_data.append(test_cluster)

    return test_data

def main():
    print("=" * 70)
    print("ROUND 2 CLUSTER SELECTION")
    print("=" * 70)

    channels = {
        'body_is_weird': {'count': 4, 'need_generic': 2, 'need_decent': 1, 'need_small': 1},
        'power_works': {'count': 3, 'need_generic': 1, 'need_decent': 1, 'need_small': 0},
        'what_actually_happened': {'count': 3, 'need_generic': 0, 'need_decent': 1, 'need_small': 1}
    }

    all_test_clusters = []

    for channel_id, params in channels.items():
        # Load data
        cluster_data, opportunities = load_channel_data(channel_id)
        clusters = cluster_data.get('clusters', [])

        # Select clusters
        selected = select_clusters_for_channel(
            channel_id,
            params['count'],
            clusters,
            opportunities,
            params['need_generic'],
            params['need_decent'],
            params['need_small']
        )

        print(f"\nSelected {len(selected)} clusters from {channel_id}:")
        for c in selected:
            size_label = "SMALL" if c['topic_count'] < 20 else "MED" if c['topic_count'] < 50 else "LARGE"
            generic_label = "GENERIC" if c.get('is_generic') else "DECENT"
            print(f"  [{c['cluster_id']}] {size_label} {generic_label} ({c['pipeline_score']:.1f}) \"{c['pipeline_title'][:50]}...\"")

        # Extract full test data
        test_data = extract_test_data(selected, channel_id)
        all_test_clusters.extend(test_data)

    # Save combined test data
    output_path = os.path.join(SANDBOX_DIR, 'round2_clusters.json')
    with open(output_path, 'w') as f:
        json.dump({
            'round': 2,
            'total_clusters': len(all_test_clusters),
            'channels': list(channels.keys()),
            'clusters': all_test_clusters
        }, f, indent=2)

    print(f"\n{'='*70}")
    print(f"Saved {len(all_test_clusters)} test clusters to {output_path}")
    print("=" * 70)

    # Summary
    total_posts = sum(len(c['raw_posts']) for c in all_test_clusters)
    total_with_content = sum(c['posts_with_content'] for c in all_test_clusters)
    generic_count = sum(1 for c in all_test_clusters if c.get('is_generic_baseline'))
    small_count = sum(1 for c in all_test_clusters if c['topic_count'] < 20)

    print(f"\nSummary:")
    print(f"  Total raw posts: {total_posts}")
    print(f"  Posts with content: {total_with_content}")
    print(f"  Generic baseline titles: {generic_count}")
    print(f"  Small clusters (<20): {small_count}")

if __name__ == "__main__":
    main()
