#!/usr/bin/env python3
"""Strip album_artist=Various Artists (and empty album_artist TPE2 frames) from MP3 files.

Walks a directory recursively, removes the album_artist tag when it's
"Various Artists" (case-insensitive) or when it's an empty/missing TPE2 frame.
All other tags (title, artist, album, year, genre, etc.) are untouched.

Usage:
    # Process a directory
    python3 strip-various-artists.py /mnt/seagate8tb/Music/Albanian/

    # Dry-run — show what would change without modifying files
    python3 strip-various-artists.py --dry-run /path/to/music/

    # Specific artist name to strip (default: "Various Artists")
    python3 strip-various-artists.py --artist="Various" /path/to/music/

After running: Plex will NOT re-read the tags on a normal refresh.
Use the "Plex Dance" (remove location → empty trash → re-add → scan)
to force Plex to process the corrected tags from scratch.

Requirements: pip install mutagen
"""

import argparse
import os
import sys

try:
    from mutagen.easyid3 import EasyID3
    from mutagen.id3 import ID3
except ImportError:
    sys.exit("mutagen is required. Install: pip install mutagen")


def strip_album_artist(filepath: str, target_artist: str, dry_run: bool) -> str | None:
    """Remove album_artist from a file if it matches target_artist or is empty.
    Returns the old value if removed, None otherwise."""
    try:
        audio = EasyID3(filepath)
        aa = audio.get("albumartist", [None])[0]

        if aa and aa.lower() == target_artist.lower():
            if not dry_run:
                del audio["albumartist"]
                audio.save()
            return aa

        if not aa:
            # Empty/missing album_artist via EasyID3 — check raw TPE2
            try:
                id3 = ID3(filepath)
                if "TPE2" in id3:
                    old_val = str(id3["TPE2"])
                    if not dry_run:
                        del id3["TPE2"]
                        id3.save()
                    return f"(empty TPE2: {old_val})"
            except Exception:
                pass

    except Exception as e:
        return f"ERROR: {e}"

    return None


def main():
    parser = argparse.ArgumentParser(
        description="Strip album_artist=Various Artists from MP3 files"
    )
    parser.add_argument("path", help="Directory to scan recursively")
    parser.add_argument(
        "--dry-run", action="store_true", help="Show what would change without modifying files"
    )
    parser.add_argument(
        "--artist",
        default="Various Artists",
        help='Target album_artist value to strip (default: "Various Artists")',
    )
    args = parser.parse_args()

    if not os.path.isdir(args.path):
        sys.exit(f"Not a directory: {args.path}")

    fixed = 0
    errors = 0
    skipped = 0

    for root, dirs, files in os.walk(args.path):
        for fname in files:
            if not fname.lower().endswith(".mp3"):
                continue
            fpath = os.path.join(root, fname)
            result = strip_album_artist(fpath, args.artist, args.dry_run)
            if result:
                if result.startswith("ERROR"):
                    print(f"  ERROR: {fpath} — {result}")
                    errors += 1
                else:
                    action = "WOULD strip" if args.dry_run else "Stripped"
                    print(f"  {action}: {os.path.relpath(fpath, args.path)} (was: {result})")
                    fixed += 1
            else:
                skipped += 1

    action = "Would fix" if args.dry_run else "Fixed"
    print(f"\n{action}: {fixed}, Errors: {errors}, Skipped (no match): {skipped}")


if __name__ == "__main__":
    main()
