#!/usr/bin/env python3
"""Fix tagged users for recently backfilled kyliejenner posts.

Fetches each post via /api/v1/media/{code}/info/ and inserts tagged users.
"""
import json
import string
import sys
import time
import os

sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
import modules.db_bootstrap  # noqa: F401

import sqlite3
from curl_cffi.requests import Session as CurlSession
from datetime import datetime

CREATOR_ID = 110
SLEEP_BETWEEN = 1.5

CHARSET = string.ascii_uppercase + string.ascii_lowercase + string.digits + '-_'

def shortcode_to_media_id(code):
    media_id = 0
    for char in code:
        media_id = media_id * 64 + CHARSET.index(char)
    return str(media_id)


def main():
    conn = sqlite3.connect('media_downloader')
    cursor = conn.cursor()

    # Load cookies
    cursor.execute("SELECT cookies_json FROM scrapers WHERE id = 'instagram_browser'")
    cookie_list = json.loads(cursor.fetchone()[0])

    # Get the backfilled posts
    cursor.execute("""
        SELECT p.id, p.post_id FROM paid_content_posts p
        WHERE p.creator_id = ? AND p.added_at >= '2026-03-28T21:00:00'
        ORDER BY p.id
    """, (CREATOR_ID,))
    posts = cursor.fetchall()
    print(f"Found {len(posts)} posts to check for tags")

    session = CurlSession(impersonate='edge101')
    session.headers.update({
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36 Edg/131.0.0.0',
        'X-IG-App-ID': '936619743392459',
        'X-Requested-With': 'XMLHttpRequest',
        'Referer': 'https://www.instagram.com/',
        'Origin': 'https://www.instagram.com',
        'Sec-CH-UA': '"Microsoft Edge";v="131", "Chromium";v="131", "Not_A Brand";v="24"',
        'Sec-CH-UA-Mobile': '?0',
        'Sec-CH-UA-Platform': '"Windows"',
        'Sec-Fetch-Dest': 'empty',
        'Sec-Fetch-Mode': 'cors',
        'Sec-Fetch-Site': 'same-origin',
    })
    for c in cookie_list:
        if c.get('name') and c.get('value'):
            session.cookies.set(c['name'], c['value'], domain=c.get('domain', '.instagram.com'))

    tagged_count = 0
    now = datetime.now().isoformat()

    for i, (db_id, code) in enumerate(posts):
        try:
            media_id = shortcode_to_media_id(code)
            resp = session.get(
                f'https://www.instagram.com/api/v1/media/{media_id}/info/',
                timeout=10
            )
            if resp.status_code != 200:
                print(f"  [{i+1}/{len(posts)}] {code}: HTTP {resp.status_code}")
                if resp.status_code == 429:
                    print("  Rate limited, waiting 60s...")
                    time.sleep(60)
                continue

            data = resp.json()
            items = data.get('items', [])
            if not items:
                print(f"  [{i+1}/{len(posts)}] {code}: no items")
                continue

            node = items[0]
            tagged_users = []
            for tag in (node.get('usertags') or {}).get('in', []):
                uname = (tag.get('user') or {}).get('username')
                if uname and uname not in tagged_users:
                    tagged_users.append(uname)
            for cm in node.get('carousel_media') or []:
                for tag in (cm.get('usertags') or {}).get('in', []):
                    uname = (tag.get('user') or {}).get('username')
                    if uname and uname not in tagged_users:
                        tagged_users.append(uname)

            if tagged_users:
                for uname in tagged_users:
                    cursor.execute(
                        """INSERT INTO paid_content_post_tagged_users (post_id, username, created_at)
                           VALUES (?, ?, ?) ON CONFLICT (post_id, username) DO NOTHING""",
                        (db_id, uname, now)
                    )
                conn.commit()
                tagged_count += 1
                print(f"  [{i+1}/{len(posts)}] {code}: {', '.join(tagged_users)}")
            else:
                if (i + 1) % 50 == 0:
                    print(f"  [{i+1}/{len(posts)}] progress... ({tagged_count} tagged so far)")

        except Exception as e:
            print(f"  [{i+1}/{len(posts)}] {code}: error: {e}")

        time.sleep(SLEEP_BETWEEN)

    conn.close()
    print(f"\nDone! Tagged {tagged_count} posts out of {len(posts)}.")


if __name__ == '__main__':
    main()
