"""Top-level workflows.

`run_fetch` does *all* the work incrementally and reports: pull Spotify, scan
the local library, parse the iTunes export, resolve MBIDs, then match. The first
run is slow (initial scan + MusicBrainz lookups); later runs only touch what
changed, so they're quick.
"""
import logging
import subprocess
import sys
import time

from Env import (
    client_id,
    client_secret,
    itunes_xml_path,
    local_library_path,
    spotify_cache_dir,
)
from src.db.database import init_db
from src.enrich.mbid import resolve_mbids, unresolved_count
from src.ingest.itunes_xml import ingest_itunes
from src.ingest.local_scan import scan_local
from src.ingest.spotify_fetch import fetch_spotify_incremental
from src.ingest.spotify_raw import ingest_spotify
from src.match.matcher import summary

log = logging.getLogger("musicindexer")


def _step(title):
    log.info("")
    log.info("== %s", title)


def run_fetch(enrich_limit=None, enrich=True, spotify_full=False, include_top=False):
    started = time.time()
    init_db()
    log.info("MusicIndexer — incremental fetch")
    log.info("  local library : %s", local_library_path)
    log.info("  itunes xml    : %s", itunes_xml_path)
    log.info("  spotify cache : %s", spotify_cache_dir)
    log.info("  top tracks    : %s", "included" if include_top else "excluded (liked + playlists only)")

    _step("Spotify")
    if client_id and client_secret:
        log.info("credentials present -> incremental live fetch%s",
                 " (full resync)" if spotify_full else "")
        try:
            fetch_spotify_incremental(full=spotify_full, include_top=include_top)
        except Exception as exc:  # keep going on cached data
            log.error("live fetch failed (%s); falling back to cached responses", exc)
            ingest_spotify(include_top=include_top)
    else:
        log.info("no SPOTIFY_CLIENT_ID/SECRET -> using cached responses")
        ingest_spotify(include_top=include_top)

    _step("iTunes")
    ingest_itunes()

    _step("Local library")
    scan_local()

    _step("MusicBrainz enrichment (incremental)")
    if not enrich:
        log.info("skipped (using MBIDs already on tracks, e.g. local tags)")
    else:
        todo = unresolved_count()
        log.info("%d tracks still need an MBID", todo)
        if todo:
            stats = resolve_mbids(limit=enrich_limit)
            log.info("resolved this run: %s", stats)
            log.info("remaining unresolved: %d", unresolved_count())

    _step("Matching")
    summ = summary()
    for source in ("spotify", "itunes"):
        s = summ.get(source)
        if s:
            log.info("%-7s total=%-5d MISSING=%-5d have(id)=%-5d have(text)=%-5d",
                     source, s["total"], s["missing"], s["present_mbid"], s["present_text"])
    sp = summ.get("spotify")
    if sp:
        log.info("spotify origins: liked=%d playlist=%d top=%d",
                 sp.get("liked", 0), sp.get("from_playlist", 0), sp.get("from_top", 0))
    local = summ.get("local", {})
    log.info("local   total=%-5d with_mbid=%d", local.get("total", 0), local.get("has_mbid", 0))

    log.info("")
    log.info("done in %.1fs — run `python main.py display` to browse what's missing",
             time.time() - started)
    return summ


def run_display():
    """Launch the Streamlit GUI."""
    subprocess.run([sys.executable, "-m", "streamlit", "run", "Gui.py"])
