"""Re-fetch sub-hosters dla dooplay movies (pandamovies/mangoporn/streamporn)
zaingestowanych PRZED fixem markupu commit 12a897b (2026-05-16 15:55).

Symptom: movie ma TYLKO raw landing playback_source (`origin='pandamovies'` plain,
bez sub-hostera). User otwiera w WebView → ad redirect → no video. Bug-reports
22:13-22:15 (2026-05-17) confirmed.

Logika:
  1. Find movies gdzie origin pandamovies/mangoporn/streamporn + tylko 1 raw playback
  2. Re-fetch detail HTML
  3. Run dooplay extractor → RawMovie z sub-hosters
  4. _sync_playback_sources insert/upsert (resolver helper)

Uruchomienie: docker exec goon-api-1 python -m scripts.repair_dooplay_movies [--site=pandamovies] [--limit=20]
"""
from __future__ import annotations

import argparse
import logging
import uuid

import sqlalchemy as sa

from app.connectors.dooplay import (
    MangopornConnector,
    PandamoviesConnector,
    StreampornConnector,
)
from app.db import session_scope
from app.models.movie import Movie
from app.models.movie_playback_source import MoviePlaybackSource
from app.normalize.movies import normalize_movie
from app.resolve.movie_resolver import _sync_playback_sources

log = logging.getLogger(__name__)

CONNECTORS = {
    "pandamovies": PandamoviesConnector,
    "mangoporn": MangopornConnector,
    "streamporn": StreampornConnector,
}


def repair(site: str, limit: int) -> dict:
    cls = CONNECTORS[site]
    conn = cls()
    counters = {"checked": 0, "added_hosters": 0, "fetch_fail": 0, "no_hosters": 0}

    with session_scope() as session:
        # Find movies o tym origin + tylko 1 raw playback (brak sub-hosterów)
        bad_movie_ids = session.execute(
            sa.text("""
                SELECT m.id, mps.page_url
                FROM movies m
                JOIN movie_playback_sources mps ON mps.movie_id = m.id
                WHERE mps.origin = :origin
                  AND (SELECT COUNT(*) FROM movie_playback_sources mps2
                       WHERE mps2.movie_id = m.id) = 1
                LIMIT :limit
            """),
            {"origin": site, "limit": limit},
        ).all()

        log.info("%s: %d movies needing repair", site, len(bad_movie_ids))
        for movie_id, page_url in bad_movie_ids:
            counters["checked"] += 1
            try:
                raw_movie = conn._fetch_detail(page_url)
            except Exception as e:
                log.warning("fetch %s failed: %s", page_url, e)
                counters["fetch_fail"] += 1
                continue
            if raw_movie is None:
                log.warning("fetch %s returned None", page_url)
                counters["fetch_fail"] += 1
                continue

            # _sync_playback_sources oczekuje NormalizedMovie
            norm = normalize_movie(raw_movie)
            before_count = session.execute(
                sa.text("SELECT COUNT(*) FROM movie_playback_sources WHERE movie_id = :mid"),
                {"mid": movie_id},
            ).scalar()

            movie = session.get(Movie, movie_id)
            if movie is None:
                continue
            _sync_playback_sources(session, movie_id=movie_id, norm=norm)
            session.flush()

            after_count = session.execute(
                sa.text("SELECT COUNT(*) FROM movie_playback_sources WHERE movie_id = :mid"),
                {"mid": movie_id},
            ).scalar()
            added = (after_count or 0) - (before_count or 0)
            if added > 0:
                counters["added_hosters"] += added
                log.info("repaired %s: +%d hosters (%s)", movie_id, added, raw_movie.title[:50])
            else:
                counters["no_hosters"] += 1
                log.info("no new hosters for %s (%s)", movie_id, raw_movie.title[:50])
            session.commit()
    return counters


def main() -> int:
    parser = argparse.ArgumentParser()
    parser.add_argument("--site", choices=list(CONNECTORS), default="pandamovies")
    parser.add_argument("--limit", type=int, default=50)
    args = parser.parse_args()
    logging.basicConfig(level=logging.INFO, format="%(asctime)s %(levelname)s %(message)s")
    counters = repair(args.site, args.limit)
    log.info("done: %s", counters)
    return 0


if __name__ == "__main__":
    raise SystemExit(main())
