#!/usr/bin/env python3
"""
Check Fansly attachments for 4K variants and upgrade if available.

This script:
1. Finds all non-4K video attachments from Fansly Direct
2. Re-fetches media info from the Fansly API
3. Checks if a higher resolution variant is available
4. Updates the attachment URL and resets for re-download if upgrade found
"""

import asyncio
import sys
import os

# Add project to path
sys.path.insert(0, '/opt/media-downloader')

# Bootstrap PostgreSQL adapter before any database imports
from modules.db_bootstrap import bootstrap_database
bootstrap_database()

from modules.paid_content.fansly_direct_client import FanslyDirectClient
from modules.paid_content.db_adapter import PaidContentDB


async def check_and_upgrade_attachments():
    """Check all non-4K Fansly attachments for upgrades."""

    db = PaidContentDB('/opt/media-downloader/database/media_downloader.db')

    # Get Fansly auth token
    service = db.get_service('fansly_direct')
    if not service or not service.get('session_cookie'):
        print("ERROR: No Fansly auth token configured")
        return

    auth_token = service['session_cookie']
    client = FanslyDirectClient(auth_token)

    # Find non-4K video attachments from Fansly Direct
    # 4K is 3840x2160 or 2160x3840 (portrait)
    query = """
        SELECT a.id, a.name, a.width, a.height, a.status, p.post_id, p.id as db_post_id
        FROM paid_content_attachments a
        JOIN paid_content_posts p ON a.post_id = p.id
        JOIN paid_content_creators c ON p.creator_id = c.id
        WHERE c.service_id = 'fansly_direct'
          AND a.file_type = 'video'
          AND a.width IS NOT NULL
          AND a.height IS NOT NULL
          AND NOT (
              (a.width >= 3840 AND a.height >= 2160) OR
              (a.width >= 2160 AND a.height >= 3840)
          )
          AND p.post_id NOT LIKE 'manual_%'
          AND p.post_id NOT LIKE 'import_%'
          AND p.post_id NOT LIKE '20%-%'
        ORDER BY a.id
    """

    cursor = db.conn.execute(query)
    attachments = cursor.fetchall()

    print(f"Found {len(attachments)} non-4K video attachments to check")
    print("-" * 80)

    upgrades_found = 0
    errors = 0
    already_best = 0

    for att in attachments:
        att_id, name, width, height, status, post_id, db_post_id = att
        current_res = f"{width}x{height}"

        print(f"\nChecking: {name} (ID: {att_id}, current: {current_res})")

        try:
            # Extract media ID from filename (e.g., "12345.mp4" -> "12345")
            media_id = name.replace('.mp4', '').replace('.mov', '')

            # Fetch media info from Fansly API
            # We need to get the account media for this post
            async with client:
                # Get the post to find media info
                posts, _, media_dict, account_media_dict, bundle_dict = await client._fetch_timeline_page(
                    account_id=None,  # We'll search by post ID
                    before=str(int(post_id) + 1),  # Get this post
                    account={}
                )

                # Find media in the dictionaries
                found_4k = False
                best_width = width
                best_height = height
                best_url = None

                # Check account_media_dict for this media
                for am_id, am_data in account_media_dict.items():
                    media = am_data.get('media', {})
                    if str(media.get('id')) == media_id:
                        # Found the media, check variants
                        variants = media.get('variants', [])
                        print(f"  Found media with {len(variants)} variants")

                        for v in variants:
                            v_w = v.get('width', 0) or 0
                            v_h = v.get('height', 0) or 0
                            v_locs = v.get('locations', [])

                            # Check if this is a higher resolution
                            if v_w * v_h > best_width * best_height:
                                for loc in v_locs:
                                    loc_url = loc.get('location', '')
                                    # Prefer streaming formats for 4K
                                    if '.m3u8' in loc_url or '.mp4' in loc_url or '.mov' in loc_url:
                                        best_width = v_w
                                        best_height = v_h

                                        # Construct signed URL if metadata present
                                        metadata = loc.get('metadata', {})
                                        if metadata:
                                            params = []
                                            for key in ['Key-Pair-Id', 'Signature', 'Policy']:
                                                if key in metadata:
                                                    params.append(f"{key}={metadata[key]}")
                                            if params:
                                                best_url = loc_url + '?' + '&'.join(params)
                                            else:
                                                best_url = loc_url
                                        else:
                                            best_url = loc_url

                                        if v_w >= 3840 or v_h >= 3840:
                                            found_4k = True
                                        break
                        break

                if found_4k and best_url:
                    print(f"  ✓ UPGRADE FOUND: {best_width}x{best_height}")
                    upgrades_found += 1

                    # Update the attachment
                    db.conn.execute("""
                        UPDATE paid_content_attachments
                        SET download_url = ?,
                            width = ?,
                            height = ?,
                            status = 'pending',
                            download_attempts = 0,
                            error_message = NULL,
                            local_path = NULL,
                            local_filename = NULL
                        WHERE id = ?
                    """, (best_url, best_width, best_height, att_id))
                    db.conn.commit()
                    print(f"  → Updated and queued for re-download")

                elif best_width > width or best_height > height:
                    print(f"  ~ Better quality available: {best_width}x{best_height} (not 4K)")
                else:
                    print(f"  - Already at best available quality")
                    already_best += 1

        except Exception as e:
            print(f"  ✗ Error: {e}")
            errors += 1

        # Rate limiting
        await asyncio.sleep(0.5)

    print("\n" + "=" * 80)
    print(f"Summary:")
    print(f"  Upgrades found and queued: {upgrades_found}")
    print(f"  Already at best quality: {already_best}")
    print(f"  Errors: {errors}")
    print(f"  Total checked: {len(attachments)}")


if __name__ == '__main__':
    asyncio.run(check_and_upgrade_attachments())
