"""CLI: orphan-only Magento gallery cleanup for assigned (or explicit) SKUs.

Keeps master desired images; deletes live gallery entries that are not mapped
to current master URLs. Does not wipe galleries and does not re-upload.

Examples:
  python -m app.jobs.magento_media_cleanup --connection-id 4 --all-assigned --dry-run
  python -m app.jobs.magento_media_cleanup --connection-id 4 --all-assigned --apply
  python -m app.jobs.magento_media_cleanup --connection-id 4 --sku ACH-B12 --sku ACH-B15 --apply
"""

from __future__ import annotations

import argparse
import json
import logging
from typing import Any, Dict, List, Optional, Sequence

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)


def run_magento_media_cleanup(
    *,
    connection_id: int,
    skus: Optional[Sequence[str]] = None,
    all_assigned: bool = False,
    apply: bool = False,
    purge_unmapped: bool = True,
    batch_size: int = 250,
    offset: int = 0,
    limit: Optional[int] = None,
) -> Dict[str, Any]:
    from db.magento_repositories import (
        SqlAlchemyMagentoCatalogStateRepository,
        SqlAlchemyMagentoConnectionRepository,
        SqlAlchemyMagentoMediaMapRepository,
    )
    from db.session import get_session
    from magento.magento_api import MagentoRestClient
    from magento.media_cleanup import (
        cleanup_orphaned_media_batch,
        resolve_orphan_cleanup_skus,
    )
    from magento.oauth_client import MagentoOAuthClient, build_magento_oauth_kwargs

    dry_run = not bool(apply)
    with get_session() as session:
        conn = SqlAlchemyMagentoConnectionRepository(session).get_for_sync(connection_id)
        if not conn:
            return {
                "status": "failed",
                "error": f"Magento connection {connection_id} not found",
            }

        targets = resolve_orphan_cleanup_skus(
            session,
            skus=list(skus) if skus else None,
            all_assigned=bool(all_assigned),
            offset=int(offset or 0),
            limit=limit,
        )
        if not targets:
            return {
                "status": "dry_run" if dry_run else "ok",
                "mode": "orphans_only",
                "connection_id": connection_id,
                "sku_count": 0,
                "message": "No SKUs matched for Magento orphan media cleanup.",
            }

        oauth = MagentoOAuthClient(**build_magento_oauth_kwargs(conn))
        api = MagentoRestClient(oauth)
        summary = cleanup_orphaned_media_batch(
            connection_id=connection_id,
            skus=targets,
            api=api,
            media_repo=SqlAlchemyMagentoMediaMapRepository(session),
            catalog_repo=SqlAlchemyMagentoCatalogStateRepository(session),
            session=session,
            dry_run=dry_run,
            purge_unmapped=bool(purge_unmapped),
            batch_size=max(1, int(batch_size or 250)),
            include_sku_results=dry_run and len(targets) <= 100,
        )
        session.commit()
        return {
            "mode": "orphans_only",
            "connection_id": connection_id,
            "sku_count": len(targets),
            "dry_run": dry_run,
            **summary,
        }


def main(argv: Optional[Sequence[str]] = None) -> int:
    parser = argparse.ArgumentParser(
        description="Orphan-only Magento gallery cleanup (keep master images, remove extras)"
    )
    parser.add_argument("--connection-id", type=int, required=True)
    parser.add_argument("--sku", action="append", dest="skus", default=[], help="Target SKU; repeatable")
    parser.add_argument(
        "--all-assigned",
        action="store_true",
        help="Clean all Magento channel-assigned SKUs",
    )
    parser.add_argument("--apply", action="store_true", help="Apply deletions (default is dry-run)")
    parser.add_argument("--dry-run", action="store_true", help="Explicit dry-run (default)")
    parser.add_argument(
        "--no-purge-unmapped",
        action="store_true",
        help="Only delete stale media-map rows; leave unmapped live gallery entries",
    )
    parser.add_argument("--batch-size", type=int, default=250)
    parser.add_argument("--offset", type=int, default=0)
    parser.add_argument("--limit", type=int, default=None)
    args = parser.parse_args(list(argv) if argv is not None else None)

    if args.apply and args.dry_run:
        parser.error("Pass only one of --apply or --dry-run")
    if not args.skus and not args.all_assigned:
        parser.error("Pass --all-assigned and/or --sku")

    result = run_magento_media_cleanup(
        connection_id=int(args.connection_id),
        skus=args.skus or None,
        all_assigned=bool(args.all_assigned),
        apply=bool(args.apply),
        purge_unmapped=not bool(args.no_purge_unmapped),
        batch_size=int(args.batch_size),
        offset=int(args.offset),
        limit=args.limit,
    )
    print(json.dumps(result, indent=2, default=str))
    status = str(result.get("status") or "")
    if status in {"ok", "dry_run", "partial", "completed"} or not args.apply:
        return 0
    return 1 if status == "failed" else 0


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