#!/usr/bin/env python3
"""Backfill vocal isolation tracks for all existing audio/video products.

Usage:
    python -m make_post_sell.scripts.backfill_karaoke production.ini
    python -m make_post_sell.scripts.backfill_karaoke production.ini --execute
"""

import argparse
import sys
import transaction

from pyramid.paster import bootstrap

from make_post_sell.models.product import Product, get_media_type
from make_post_sell.lib.karaoke import process_karaoke, tracks_exist


def backfill(env, dry_run=True):
    request = env["request"]
    dbsession = request.dbsession
    s3 = request.secure_uploads_client
    bucket = request.app["bucket.secure_uploads"]

    products = dbsession.query(Product).all()
    print(f"Found {len(products)} products to scan")
    print(f"Dry run: {dry_run}")
    print("-" * 50)

    processed = 0
    skipped = 0
    errors = 0

    for product in products:
        shop = product.shop
        if not shop.unsandbox_public_key or not shop.unsandbox_secret_key:
            continue

        for file_key in ("product", "preview"):
            ext = product.extensions.get(file_key)
            if not ext:
                continue
            media_type = get_media_type(ext)
            if media_type not in ("video", "audio"):
                continue

            s3_key = f"{product.s3_path}/{file_key}"

            if tracks_exist(s3, bucket, product.s3_path):
                print(f"SKIP {product.title} ({file_key}) — tracks already exist")
                skipped += 1
                continue

            if dry_run:
                print(f"WOULD PROCESS {product.title} ({file_key})")
                continue

            print(f"PROCESSING {product.title} ({file_key})...")
            is_video = (media_type == "video")
            sizes = process_karaoke(
                s3, bucket, s3_key, product.s3_path, is_video, ext,
                public_key=shop.unsandbox_public_key,
                secret_key=shop.unsandbox_secret_key,
            )
            if sizes:
                track_ext = ext if is_video else "wav"
                for track_name in ("instrumentals", "vocals"):
                    product.set_file_metadata(track_name, track_ext, f"{track_name}.{track_ext}")
                tmp = product.file_bytes
                tmp.update(sizes)
                product.file_bytes = tmp
                dbsession.add(product)
                dbsession.flush()
                product.update_s3_acls(s3, bucket)
                print(f"  OK (instrumentals: {sizes['instrumentals']}B, vocals: {sizes['vocals']}B)")
                processed += 1
            else:
                print(f"  FAILED")
                errors += 1

    print("-" * 50)
    print(f"Processed: {processed}  Skipped: {skipped}  Errors: {errors}  Dry run: {dry_run}")


def main():
    parser = argparse.ArgumentParser(
        description="Backfill vocal isolation tracks for audio/video products"
    )
    parser.add_argument("config_uri", help="Configuration file (e.g., production.ini)")
    parser.add_argument(
        "--execute", action="store_true",
        help="Actually process files (default is dry run)",
    )
    args = parser.parse_args()

    with bootstrap(args.config_uri) as env:
        try:
            with transaction.manager:
                backfill(env, dry_run=not args.execute)
        except KeyboardInterrupt:
            print("\nCancelled")
            sys.exit(1)


if __name__ == "__main__":
    main()
