"""Prune stale Start Shopping category refs from collection landing configs."""

from __future__ import annotations

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

from db.session import get_session
from db.start_shopping_config_prune import (
    enqueue_start_shopping_outbound_pushes,
    prune_start_shopping_configs,
)

logger = logging.getLogger(__name__)


def main() -> None:
    parser = argparse.ArgumentParser(
        description=(
            "Drop or rewrite Start Shopping config refs that point at missing/"
            "inactive taxonomy categories. Optionally queue Magento + Shopify "
            "collection landing pushes for updated collections (master + outbound)."
        )
    )
    parser.add_argument(
        "--apply",
        action="store_true",
        help="Persist changes (default is dry-run)",
    )
    parser.add_argument(
        "--hub-path-slug",
        default=None,
        help="Limit to landings under this hub/parent path (e.g. kitchen-cabinets)",
    )
    parser.add_argument(
        "--collection-path",
        action="append",
        default=None,
        help="Limit to one collection path_slug (repeatable)",
    )
    parser.add_argument(
        "--no-refresh-intersections",
        action="store_true",
        help="Skip shopping_intersections resync after config updates",
    )
    parser.add_argument(
        "--push-outbound",
        action="store_true",
        help="Queue Magento + Shopify collection landing pushes for updated collections",
    )
    parser.add_argument("--magento-connection-id", type=int, default=None)
    parser.add_argument("--shopify-connection-id", type=int, default=None)
    parser.add_argument(
        "--no-sync-products",
        action="store_true",
        help="When pushing outbound, skip product sync on collection push jobs",
    )
    parser.add_argument(
        "--rewrite",
        action="append",
        default=None,
        metavar="OLD=NEW",
        help="Optional explicit path rewrite (use OLD= to drop). Repeatable.",
    )
    args = parser.parse_args()

    path_rewrites = _parse_rewrites(args.rewrite or [])
    logging.basicConfig(level=logging.INFO)
    with get_session() as session:
        result = prune_start_shopping_configs(
            session,
            path_rewrites=path_rewrites or None,
            collection_path_slugs=args.collection_path,
            hub_path_slug=args.hub_path_slug,
            dry_run=not args.apply,
            refresh_intersections=not args.no_refresh_intersections,
        )
        if args.push_outbound:
            connections = _resolve_outbound_connections(
                session,
                magento_connection_id=args.magento_connection_id,
                shopify_connection_id=args.shopify_connection_id,
            )
            result["outbound"] = enqueue_start_shopping_outbound_pushes(
                session,
                result.get("updated_path_slugs") or [],
                connections=connections["connections"],
                dry_run=not args.apply,
                sync_products=not args.no_sync_products,
            )
            result["outbound"]["skipped_channels"] = connections["skipped"]
            result["push_outbound"] = True
        if args.apply:
            session.commit()
            logger.info(
                "Pruned Start Shopping configs: updated=%s dropped_l1=%s dropped_l2=%s rewritten=%s outbound_queued=%s",
                result.get("updated_count"),
                result.get("dropped_l1"),
                result.get("dropped_l2"),
                result.get("rewritten_paths"),
                (result.get("outbound") or {}).get("queued"),
            )
        else:
            logger.info(
                "Dry-run Start Shopping prune: would update=%s dropped_l1=%s dropped_l2=%s rewritten=%s would_queue=%s",
                result.get("updated_count"),
                result.get("dropped_l1"),
                result.get("dropped_l2"),
                result.get("rewritten_paths"),
                (result.get("outbound") or {}).get("would_queue"),
            )
    print(json.dumps(result, indent=2, default=str))


def _resolve_outbound_connections(
    session,
    *,
    magento_connection_id: Optional[int],
    shopify_connection_id: Optional[int],
) -> Dict[str, Any]:
    """Resolve Magento/Shopify compat connections without failing the whole run."""
    from main import _resolve_channel_compat_connection

    connections: List[Dict[str, Any]] = []
    skipped: List[str] = []
    for channel, connection_id in (
        ("magento", magento_connection_id),
        ("shopify", shopify_connection_id),
    ):
        try:
            connections.append(_resolve_channel_compat_connection(session, channel, connection_id))
        except Exception as exc:  # noqa: BLE001 - channel optional for bulk fixer
            logger.warning("Skipping %s outbound push: %s", channel, exc)
            skipped.append(channel)
    return {"connections": connections, "skipped": skipped}


def _parse_rewrites(values: List[str]) -> dict:
    out: dict = {}
    for raw in values:
        text = str(raw or "").strip()
        if not text or "=" not in text:
            raise SystemExit(f"Invalid --rewrite value (expected OLD=NEW or OLD=): {raw!r}")
        old, new = text.split("=", 1)
        old = old.strip()
        new = new.strip() or None
        if not old:
            raise SystemExit(f"Invalid --rewrite value (empty OLD): {raw!r}")
        out[old] = new
    return out


if __name__ == "__main__":
    main()
