"""Merge duplicate tag → keep_slug. Przepisuje scene_tags z drop → keep
(z deduplikacją na (scene_id, tag_id)) i kasuje drop.

Użycie:
  python merge_tags.py <keep_slug> <drop_slug> [--dry-run]
"""
from __future__ import annotations

import argparse
import logging

from sqlalchemy import delete, select, update

from app.db import session_scope
from app.models.tag import Tag
from app.models.scene import SceneTag

log = logging.getLogger("merge_tags")


def main() -> None:
    parser = argparse.ArgumentParser()
    parser.add_argument("keep_slug")
    parser.add_argument("drop_slug")
    parser.add_argument("--dry-run", action="store_true")
    args = parser.parse_args()
    logging.basicConfig(level=logging.INFO, format="%(asctime)s %(levelname)s %(message)s")

    with session_scope() as s:
        keep = s.scalar(select(Tag).where(Tag.slug == args.keep_slug))
        drop = s.scalar(select(Tag).where(Tag.slug == args.drop_slug))
        if not keep:
            raise SystemExit(f"keep tag '{args.keep_slug}' not found")
        if not drop:
            raise SystemExit(f"drop tag '{args.drop_slug}' not found")
        log.info("keep: %s (%s)  drop: %s (%s)", keep.slug, keep.id, drop.slug, drop.id)

        # Pre-count
        keep_n = s.scalar(select(__import__("sqlalchemy").func.count()).select_from(SceneTag).where(SceneTag.tag_id == keep.id))
        drop_n = s.scalar(select(__import__("sqlalchemy").func.count()).select_from(SceneTag).where(SceneTag.tag_id == drop.id))
        log.info("scene_tags counts: keep=%d drop=%d", keep_n, drop_n)

        if args.dry_run:
            # Liczba unikalnych scen z dropem które już mają keep
            overlap = s.scalar(
                select(__import__("sqlalchemy").func.count()).select_from(
                    select(SceneTag.scene_id)
                    .where(SceneTag.tag_id == drop.id)
                    .where(
                        SceneTag.scene_id.in_(
                            select(SceneTag.scene_id).where(SceneTag.tag_id == keep.id)
                        )
                    )
                    .subquery()
                )
            )
            log.info("dry-run: would migrate %d, dedupe %d (already in keep)", drop_n - overlap, overlap)
            return

        # 1) Skasuj scene_tags drop dla scen które JUŻ mają keep (deduplikacja)
        del_stmt = delete(SceneTag).where(
            SceneTag.tag_id == drop.id,
            SceneTag.scene_id.in_(
                select(SceneTag.scene_id).where(SceneTag.tag_id == keep.id)
            ),
        )
        del_res = s.execute(del_stmt)
        log.info("deduped %d scene_tags", del_res.rowcount)

        # 2) Pozostałe scene_tags drop → przepisz na keep
        upd_stmt = update(SceneTag).where(SceneTag.tag_id == drop.id).values(tag_id=keep.id)
        upd_res = s.execute(upd_stmt)
        log.info("migrated %d scene_tags", upd_res.rowcount)

        # 3) Skasuj drop tag
        s.delete(drop)
        s.commit()
        log.info("dropped tag '%s'", args.drop_slug)


if __name__ == "__main__":
    main()
