#!/usr/bin/env bash
# Follow-up after recover_kitchen_taxonomy_fix_magento_4_1.sh
#
# Prefer the all-in-one daemon script instead of chaining recover + this:
#   bash scripts/fix_kitchen_taxonomy_all_4_1.sh
#
# Fixes master + Magento remotes for:
#   - polluted Collections dashboard rows under shopping facets
#       (Kitchen Cabinets / Accessories / Clearance Kit / Base Cabinets, …)
#   - invalid SEO intersections under shopping facets
#   - listing-path target mismatches (doors hub, mouldings/toe-kick, all-products, …)
#   - re-seed corrected finish collections from taxonomy + brochure JSON
#   - Start Shopping configs / intersections refresh
#   - collection landing push + taxonomy product outbound (connections 4 then 1)
#
# IMPORTANT: deploy the matcher/intersection/collection fixes BEFORE scheduling this.
# The mid-flight recover may have used older repair logic; this re-applies
# the corrected master + outbound contract.
#
# Default flow:
# 1) Optional: wait until recover_kitchen_taxonomy_fix_magento_4_1_latest.status is ok:
# 2) Deactivate facet-rooted SEO / polluted collection landings (master + dashboard)
# 3) Sanitize taxonomy/brochure JSON on disk (strip deep clearance-kit nests if present)
# 4) Re-seed kitchen taxonomy + brochure collection JSON (dashboard Collections source)
# 5) Repair Magento listing-path targets per connection (--provision-unmatched)
# 6) Prune/refresh Start Shopping for kitchen-cabinets
# 7) Magento collection landing repair/push (Start Shopping remotes/icons)
# 8) Magento taxonomy outbound (L3 + collection + all-products category_links)
# 9) Invalidate stale projection cache rows
#
# Env:
#   APP_ROOT                 PlytixMage root (default: script parent/..)
#   VENV_DIR                 Virtualenv directory (default: $APP_ROOT/.venv)
#   PYTHON                   Python interpreter override
#   LOG_DIR                  Log directory (default: $APP_ROOT/logs)
#   TAXONOMY_JSON            Path to kitchen_cabinets_taxonomy.json
#   BROCHURE_FOLDER          Path to corrected brochure/collection JSON folder
#   MAGENTO_CONNECTION_IDS   Order matters (default: "4 1")
#   HUB_PATH_SLUG            Default: kitchen-cabinets
#   PATH_PREFIX              Listing-path prefix for outbound SKUs (default: kitchen-cabinets)
#   DRY_RUN                  1 = preview only (default: 0)
#   WAIT_TIMEOUT             Wait timeout for outbound (default: 21600)
#   WAIT_FOR_PRIOR           1 = wait for prior recover status ok: (default: 1)
#   PRIOR_STATUS_FILE        Prior recover status file
#   WAIT_PRIOR_TIMEOUT       Seconds to wait for prior (default: 28800 = 8h)
#   WAIT_PRIOR_POLL          Poll interval seconds (default: 60)
#   RUN_COLLECTION_SEED      1 = re-import taxonomy + brochure collections (default: 1)
#   SKIP_FACET_SEO_CLEANUP   1 = skip deactivate_facet_rooted_seo_intersections (default: 0)
#   SKIP_JSON_SANITIZE       1 = skip sanitize_kitchen_collection_json rewrite (default: 0)
#   SKIP_LISTING_REPAIR      1 = skip repair_magento_listing_path_targets (default: 0)
#   SKIP_START_SHOPPING      1 = skip Start Shopping prune/refresh (default: 0)
#   SKIP_LANDING_REPAIR      1 = skip magento_collection_landing_repair (default: 0)
#   SKIP_TAXONOMY_OUTBOUND   1 = skip push_magento_taxonomy_outbound (default: 0)
#   SKIP_PROJECTION_FIX      1 = skip inspect_channel_projection --fix (default: 0)
#   START_SHOPPING_PUSH      1 = --push-outbound on prune (default: 1)
#   LANDING_SYNC_PRODUCTS    1 = sync products during landing repair (default: 0)
#   RUN_WORKER               1 = claim Magento jobs in-process while waiting (default: 1)
#   OUTBOUND_LIMIT           Optional max SKUs for taxonomy outbound (default: unset)
#
# Examples:
#   DRY_RUN=1 bash scripts/fix_kitchen_listing_seo_and_outbound_4_1.sh
#   bash scripts/fix_kitchen_listing_seo_and_outbound_4_1.sh
#   WAIT_FOR_PRIOR=0 bash scripts/fix_kitchen_listing_seo_and_outbound_4_1.sh
#   nohup env WAIT_FOR_PRIOR=1 bash scripts/fix_kitchen_listing_seo_and_outbound_4_1.sh \
#     >logs/fix_kitchen_listing_seo_and_outbound_4_1_nohup.out 2>&1 &

set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
APP_ROOT="$(cd "${APP_ROOT:-$SCRIPT_DIR/..}" && pwd)"
VENV_DIR="${VENV_DIR:-$APP_ROOT/.venv}"
if [[ -z "${PYTHON:-}" ]]; then
  if [[ -x "$VENV_DIR/bin/python" ]]; then
    PYTHON="$VENV_DIR/bin/python"
  else
    PYTHON="python"
  fi
else
  PYTHON="$PYTHON"
fi

LOG_DIR="${LOG_DIR:-$APP_ROOT/logs}"
TAXONOMY_JSON="${TAXONOMY_JSON:-../plytixftp.dev.piesol.com/kitchen_cabinets_taxonomy.json}"
BROCHURE_FOLDER="${BROCHURE_FOLDER:-../plytixftp.dev.piesol.com/brochure_json_3}"
MAGENTO_CONNECTION_IDS="${MAGENTO_CONNECTION_IDS:-4 1}"
HUB_PATH_SLUG="${HUB_PATH_SLUG:-kitchen-cabinets}"
PATH_PREFIX="${PATH_PREFIX:-kitchen-cabinets}"
DRY_RUN="${DRY_RUN:-0}"
WAIT_TIMEOUT="${WAIT_TIMEOUT:-21600}"
WAIT_FOR_PRIOR="${WAIT_FOR_PRIOR:-1}"
PRIOR_STATUS_FILE="${PRIOR_STATUS_FILE:-$LOG_DIR/recover_kitchen_taxonomy_fix_magento_4_1_latest.status}"
WAIT_PRIOR_TIMEOUT="${WAIT_PRIOR_TIMEOUT:-28800}"
WAIT_PRIOR_POLL="${WAIT_PRIOR_POLL:-60}"
RUN_COLLECTION_SEED="${RUN_COLLECTION_SEED:-1}"
SKIP_FACET_SEO_CLEANUP="${SKIP_FACET_SEO_CLEANUP:-0}"
SKIP_JSON_SANITIZE="${SKIP_JSON_SANITIZE:-0}"
SKIP_LISTING_REPAIR="${SKIP_LISTING_REPAIR:-0}"
SKIP_START_SHOPPING="${SKIP_START_SHOPPING:-0}"
SKIP_LANDING_REPAIR="${SKIP_LANDING_REPAIR:-0}"
SKIP_TAXONOMY_OUTBOUND="${SKIP_TAXONOMY_OUTBOUND:-0}"
SKIP_PROJECTION_FIX="${SKIP_PROJECTION_FIX:-0}"
START_SHOPPING_PUSH="${START_SHOPPING_PUSH:-1}"
LANDING_SYNC_PRODUCTS="${LANDING_SYNC_PRODUCTS:-0}"
RUN_WORKER="${RUN_WORKER:-1}"
OUTBOUND_LIMIT="${OUTBOUND_LIMIT:-}"

mkdir -p "$LOG_DIR"
STAMP="$(date -u +%Y%m%dT%H%M%SZ)"
LOG_FILE="$LOG_DIR/fix_kitchen_listing_seo_and_outbound_4_1_${STAMP}.log"
STATUS_FILE="$LOG_DIR/fix_kitchen_listing_seo_and_outbound_4_1_latest.status"

cd "$APP_ROOT"
export PYTHONUNBUFFERED=1

exec > >(tee -a "$LOG_FILE") 2>&1

echo "=== kitchen listing SEO + collections + outbound follow-up (connections: $MAGENTO_CONNECTION_IDS) ==="
echo "started_utc=$STAMP"
echo "app_root=$APP_ROOT"
echo "taxonomy_json=$TAXONOMY_JSON"
echo "brochure_folder=$BROCHURE_FOLDER"
echo "magento_connection_ids=$MAGENTO_CONNECTION_IDS"
echo "hub_path_slug=$HUB_PATH_SLUG"
echo "path_prefix=$PATH_PREFIX"
echo "dry_run=$DRY_RUN"
echo "wait_timeout=$WAIT_TIMEOUT"
echo "wait_for_prior=$WAIT_FOR_PRIOR"
echo "prior_status_file=$PRIOR_STATUS_FILE"
echo "wait_prior_timeout=$WAIT_PRIOR_TIMEOUT"
echo "run_collection_seed=$RUN_COLLECTION_SEED"
echo "skip_facet_seo_cleanup=$SKIP_FACET_SEO_CLEANUP"
echo "skip_json_sanitize=$SKIP_JSON_SANITIZE"
echo "skip_listing_repair=$SKIP_LISTING_REPAIR"
echo "skip_start_shopping=$SKIP_START_SHOPPING"
echo "skip_landing_repair=$SKIP_LANDING_REPAIR"
echo "skip_taxonomy_outbound=$SKIP_TAXONOMY_OUTBOUND"
echo "skip_projection_fix=$SKIP_PROJECTION_FIX"
echo "start_shopping_push=$START_SHOPPING_PUSH"
echo "landing_sync_products=$LANDING_SYNC_PRODUCTS"
echo "run_worker=$RUN_WORKER"
echo "outbound_limit=${OUTBOUND_LIMIT:-<none>}"
echo "log_file=$LOG_FILE"
echo "python=$PYTHON ($("$PYTHON" --version 2>&1 || true))"
echo

fail() {
  local step="$1"
  local code="$2"
  echo "FAILED step=$step exit=$code"
  echo "failed:$step:$code:$(date -u +%Y%m%dT%H%M%SZ)" >"$STATUS_FILE"
  exit "$code"
}

run_step() {
  local name="$1"
  shift
  echo
  echo "------------------------------------------------------------"
  echo "STEP: $name"
  echo "CMD: $*"
  echo "started: $(date -u +%Y-%m-%dT%H:%M:%SZ)"
  echo "------------------------------------------------------------"
  if "$@"; then
    echo "OK: $name ($(date -u +%Y-%m-%dT%H:%M:%SZ))"
  else
    local code=$?
    fail "$name" "$code"
  fi
}

wait_for_prior_recover() {
  local started
  started="$(date +%s)"
  echo
  echo "Waiting for prior recover status ok: in $PRIOR_STATUS_FILE"
  echo "(timeout=${WAIT_PRIOR_TIMEOUT}s poll=${WAIT_PRIOR_POLL}s)"
  while true; do
    if [[ -f "$PRIOR_STATUS_FILE" ]]; then
      local line
      line="$(tr -d '\r' <"$PRIOR_STATUS_FILE" | head -n 1 || true)"
      echo "prior_status=$(date -u +%Y-%m-%dT%H:%M:%SZ) value=${line:-<empty>}"
      if [[ "$line" == ok:* ]]; then
        echo "Prior recover completed: $line"
        return 0
      fi
      if [[ "$line" == failed:* ]]; then
        echo "Prior recover failed: $line"
        fail "wait_for_prior_recover" 2
      fi
    else
      echo "prior_status=$(date -u +%Y-%m-%dT%H:%M:%SZ) value=<missing>"
    fi
    local now elapsed
    now="$(date +%s)"
    elapsed=$((now - started))
    if (( elapsed >= WAIT_PRIOR_TIMEOUT )); then
      echo "Timed out waiting for prior recover after ${elapsed}s"
      fail "wait_for_prior_recover_timeout" 3
    fi
    sleep "$WAIT_PRIOR_POLL"
  done
}

APPLY_ARGS=()
if [[ "$DRY_RUN" == "1" ]]; then
  echo "DRY_RUN=1 - preview mode only"
else
  APPLY_ARGS+=(--apply)
fi

if [[ "$WAIT_FOR_PRIOR" == "1" ]]; then
  wait_for_prior_recover
fi

# ---------------------------------------------------------------------------
# Master-side: kill polluted Collections UI rows + SEO under accessories/...
# ---------------------------------------------------------------------------
if [[ "$SKIP_FACET_SEO_CLEANUP" != "1" ]]; then
  FACET_CMD=(
    "$PYTHON" -m app.jobs.deactivate_facet_rooted_seo_intersections
    --hub-path-slug "$HUB_PATH_SLUG"
  )
  FACET_CMD+=("${APPLY_ARGS[@]+"${APPLY_ARGS[@]}"}")
  run_step "deactivate_facet_rooted_seo_intersections" "${FACET_CMD[@]}"
fi

# ---------------------------------------------------------------------------
# Rewrite taxonomy/brochure JSON on disk if deep clearance-kit pollution exists
# ---------------------------------------------------------------------------
if [[ "$SKIP_JSON_SANITIZE" != "1" ]]; then
  JSON_CMD=(
    "$PYTHON" -m app.jobs.sanitize_kitchen_collection_json
    --taxonomy-file "$TAXONOMY_JSON"
    --brochure-folder "$BROCHURE_FOLDER"
  )
  JSON_CMD+=("${APPLY_ARGS[@]+"${APPLY_ARGS[@]}"}")
  run_step "sanitize_kitchen_collection_json" "${JSON_CMD[@]}"
fi

# ---------------------------------------------------------------------------
# Re-seed corrected finish collections from taxonomy + brochure JSON
# (source of truth for https://plytixdash.../#/collections)
# ---------------------------------------------------------------------------
if [[ "$RUN_COLLECTION_SEED" == "1" ]]; then
  SEED_CMD=(
    "$PYTHON" -m app.jobs.import_kitchen_cabinets_taxonomy
    --file "$TAXONOMY_JSON"
    --brochure-folder "$BROCHURE_FOLDER"
  )
  SEED_CMD+=("${APPLY_ARGS[@]+"${APPLY_ARGS[@]}"}")
  run_step "import_kitchen_cabinets_taxonomy_collections" "${SEED_CMD[@]}"

  # Also seed commerce profiles / landing metadata from brochure folder directly
  # so Collections dashboard content matches corrected JSON even when taxonomy
  # twin expansion skips some brochure-only collections.
  BROCHURE_SEED_CMD=(
    "$PYTHON" -m app.jobs.seed_collection_brochure
    --folder "$BROCHURE_FOLDER"
  )
  FIRST_MAGENTO_ID=""
  for magento_id in $MAGENTO_CONNECTION_IDS; do
    FIRST_MAGENTO_ID="$magento_id"
    break
  done
  if [[ -n "$FIRST_MAGENTO_ID" ]]; then
    BROCHURE_SEED_CMD+=(--channel magento --connection-id "$FIRST_MAGENTO_ID")
  fi
  BROCHURE_SEED_CMD+=("${APPLY_ARGS[@]+"${APPLY_ARGS[@]}"}")
  run_step "seed_collection_brochure_folder" "${BROCHURE_SEED_CMD[@]}"
fi

# ---------------------------------------------------------------------------
# Master-side Start Shopping prune / intersection refresh (shared across Magento)
# ---------------------------------------------------------------------------
if [[ "$SKIP_START_SHOPPING" != "1" ]]; then
  FIRST_MAGENTO_ID=""
  for magento_id in $MAGENTO_CONNECTION_IDS; do
    FIRST_MAGENTO_ID="$magento_id"
    break
  done
  SS_CMD=(
    "$PYTHON" -m app.jobs.prune_start_shopping_config
    --hub-path-slug "$HUB_PATH_SLUG"
  )
  if [[ -n "$FIRST_MAGENTO_ID" ]]; then
    SS_CMD+=(--magento-connection-id "$FIRST_MAGENTO_ID")
  fi
  if [[ "$START_SHOPPING_PUSH" == "1" ]]; then
    SS_CMD+=(--push-outbound --no-sync-products)
  fi
  SS_CMD+=("${APPLY_ARGS[@]+"${APPLY_ARGS[@]}"}")
  run_step "prune_start_shopping_config" "${SS_CMD[@]}"
fi

# ---------------------------------------------------------------------------
# Per Magento connection: listing targets → landings push → taxonomy outbound
# ---------------------------------------------------------------------------
for magento_id in $MAGENTO_CONNECTION_IDS; do
  echo
  echo "############################################################"
  echo "# Magento connection $magento_id"
  echo "############################################################"

  if [[ "$SKIP_LISTING_REPAIR" != "1" ]]; then
    LISTING_CMD=(
      "$PYTHON" -m app.jobs.repair_magento_listing_path_targets
      --connection-id "$magento_id"
      --provision-unmatched
    )
    LISTING_CMD+=("${APPLY_ARGS[@]+"${APPLY_ARGS[@]}"}")
    run_step "repair_magento_listing_path_targets_conn_${magento_id}" "${LISTING_CMD[@]}"
  fi

  if [[ "$SKIP_LANDING_REPAIR" != "1" ]]; then
    LANDING_CMD=(
      "$PYTHON" -m app.jobs.magento_collection_landing_repair
      --connection-id "$magento_id"
      --category-l1 "Kitchen Cabinets"
    )
    if [[ "$LANDING_SYNC_PRODUCTS" == "1" ]]; then
      LANDING_CMD+=(--sync-products)
    fi
    LANDING_CMD+=("${APPLY_ARGS[@]+"${APPLY_ARGS[@]}"}")
    run_step "magento_collection_landing_repair_push_conn_${magento_id}" "${LANDING_CMD[@]}"
  fi

  if [[ "$SKIP_TAXONOMY_OUTBOUND" != "1" ]]; then
    OUTBOUND_CMD=(
      "$PYTHON" -m app.jobs.push_magento_taxonomy_outbound
      --connection-id "$magento_id"
      --path-prefix "$PATH_PREFIX"
      --wait
    )
    if [[ "$RUN_WORKER" == "1" ]]; then
      OUTBOUND_CMD+=(--run-worker)
    fi
    if [[ -n "$OUTBOUND_LIMIT" ]]; then
      OUTBOUND_CMD+=(--limit "$OUTBOUND_LIMIT")
    fi
    OUTBOUND_CMD+=("${APPLY_ARGS[@]+"${APPLY_ARGS[@]}"}")
    run_step "push_magento_taxonomy_outbound_conn_${magento_id}" "${OUTBOUND_CMD[@]}"
  fi

  if [[ "$SKIP_PROJECTION_FIX" != "1" ]]; then
    PROJECTION_CMD=(
      "$PYTHON" -m app.jobs.inspect_channel_projection
      --channel magento
      --connection-id "$magento_id"
    )
    if [[ "$DRY_RUN" != "1" ]]; then
      PROJECTION_CMD+=(--fix)
    fi
    run_step "inspect_channel_projection_magento_conn_${magento_id}" "${PROJECTION_CMD[@]}"
  fi
done

echo
echo "=== completed successfully $(date -u +%Y-%m-%dT%H:%M:%SZ) ==="
echo "ok:$(date -u +%Y%m%dT%H%M%SZ)" >"$STATUS_FILE"
echo "status_file=$STATUS_FILE"
echo "log_file=$LOG_FILE"
