#!/usr/bin/env python3
"""
Retry Failed Videos Tool for Maya3 Pipeline.

Resets FAILED videos back to PENDING for retry processing.
Supports filtering by error type and limiting retry attempts.

Usage:
    python retry_failed.py                     # Preview what would be retried
    python retry_failed.py --execute           # Actually reset videos
    python retry_failed.py --error-type NetworkError --execute  # Specific errors
    python retry_failed.py --max-retries 3     # Only retry videos with < 3 attempts
"""

import os
import sys
import argparse
from datetime import datetime, timezone
from typing import List, Dict

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

from dotenv import load_dotenv
load_dotenv()

from supabase import create_client


def get_failed_videos(
    sb,
    error_type: str = None,
    max_retries: int = 3,
    limit: int = 1000
) -> List[Dict]:
    """Get failed videos that can be retried."""
    query = sb.table('videos').select(
        'youtube_id, title, last_error_type, last_error, attempt_count'
    ).eq('status', 'FAILED')

    if error_type:
        query = query.eq('last_error_type', error_type)

    # Only retry videos under max attempts
    query = query.lt('attempt_count', max_retries)

    result = query.order('updated_at', desc=True).limit(limit).execute()
    return result.data or []


def reset_to_pending(sb, video_ids: List[str]) -> int:
    """Reset videos to PENDING status."""
    if not video_ids:
        return 0

    now = datetime.now(timezone.utc).isoformat()

    # Batch update
    for vid in video_ids:
        sb.table('videos').update({
            'status': 'PENDING',
            'claimed_by': None,
            'claimed_at': None,
            'lease_expires_at': None,
            'updated_at': now
        }).eq('youtube_id', vid).execute()

    return len(video_ids)


def main():
    parser = argparse.ArgumentParser(description="Retry Failed Videos")
    parser.add_argument('--execute', action='store_true', help='Actually reset videos (default: preview)')
    parser.add_argument('--error-type', type=str, help='Filter by error type')
    parser.add_argument('--max-retries', type=int, default=3, help='Max retry attempts (default: 3)')
    parser.add_argument('--limit', type=int, default=100, help='Max videos to retry (default: 100)')
    args = parser.parse_args()

    sb = create_client(os.environ['URL'], os.environ['SUPABASE_ADMIN'])

    # Get failed videos
    failed = get_failed_videos(
        sb,
        error_type=args.error_type,
        max_retries=args.max_retries,
        limit=args.limit
    )

    print(f"Found {len(failed)} failed videos eligible for retry")
    print(f"  Max retries: {args.max_retries}")
    if args.error_type:
        print(f"  Error filter: {args.error_type}")

    if not failed:
        print("No videos to retry")
        return

    # Show preview
    print("\nPreview (first 10):")
    print("-" * 80)

    error_counts = {}
    for v in failed:
        err_type = v.get('last_error_type', 'Unknown')
        error_counts[err_type] = error_counts.get(err_type, 0) + 1

    for v in failed[:10]:
        vid = v['youtube_id']
        title = (v.get('title') or '')[:40]
        err_type = v.get('last_error_type', 'Unknown')
        attempts = v.get('attempt_count', 0)
        print(f"  {vid} | attempt {attempts} | {err_type}: {title}")

    if len(failed) > 10:
        print(f"  ... and {len(failed) - 10} more")

    print("\nError breakdown:")
    for err_type, count in sorted(error_counts.items(), key=lambda x: -x[1]):
        print(f"  {err_type}: {count}")

    if args.execute:
        print(f"\nResetting {len(failed)} videos to PENDING...")
        video_ids = [v['youtube_id'] for v in failed]
        count = reset_to_pending(sb, video_ids)
        print(f"Done! Reset {count} videos")
    else:
        print(f"\n[DRY RUN] Add --execute to reset {len(failed)} videos")


if __name__ == "__main__":
    main()
