#!/usr/bin/env bash
# Overnight Magento connection cleanup + full publish.
#
# Usage:
#   ./scripts/overnight_magento_cleanup_publish.sh
#   MAGENTO_CONNECTION_ID=4 DRY_RUN=1 ./scripts/overnight_magento_cleanup_publish.sh
#   MAGENTO_CONNECTION_ID=4 ./scripts/overnight_magento_cleanup_publish.sh
#
# Env:
#   MAGENTO_CONNECTION_ID  default: 4
#   DRY_RUN                1 = preview only (no --apply / no hard deletes)
#   PYTHON                 python interpreter (default: python)
#   APP_ROOT               PlytixMage root (default: script parent/..)
#   LOG_DIR                log directory (default: $APP_ROOT/logs)
#   WAIT_TIMEOUT           channel_full_publish wait seconds (default: 14400)
#   RUN_ATTRIBUTE_REPAIR   1 = ensure/push repair attributes after full publish
#   RUN_TAXONOMY_REPAIR    1 = repair listing-path targets and live product category links
#   ATTRIBUTE_BUNDLES      space-separated push_magento_attributes bundles (default: specs)
#   ATTRIBUTE_FIELDS       space-separated extra field codes appended to the bundle push
#   ATTRIBUTE_SYNC_OPTIONS 1 = sync missing select options from master during repair push
#   ATTRIBUTE_WAIT_TIMEOUT attribute repair wait seconds (default: 21600)
#   PROVISION_MISSING_ATTRIBUTES 1 = create missing mapped Magento attributes before repair push

set -euo pipefail

MAGENTO_CONNECTION_ID="${MAGENTO_CONNECTION_ID:-4}"
DRY_RUN="${DRY_RUN:-0}"
PYTHON="${PYTHON:-python}"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
APP_ROOT="$(cd "${APP_ROOT:-$SCRIPT_DIR/..}" && pwd)"
LOG_DIR="${LOG_DIR:-$APP_ROOT/logs}"
WAIT_TIMEOUT="${WAIT_TIMEOUT:-14400}"
HUB_PATH_SLUG="${HUB_PATH_SLUG:-kitchen-cabinets}"
RUN_TAXONOMY_REPAIR="${RUN_TAXONOMY_REPAIR:-1}"
RUN_ATTRIBUTE_REPAIR="${RUN_ATTRIBUTE_REPAIR:-1}"
ATTRIBUTE_BUNDLES="${ATTRIBUTE_BUNDLES:-specs}"
ATTRIBUTE_FIELDS="${ATTRIBUTE_FIELDS:-manufacturer family collection_style depth soft_close packaged_dimension_height packaged_dimension_width packaged_dimension_depth packaged_gross_weight cabinet_type base_cabinets wall_cabinets panels_and_fillers mouldings angle drawer_box}"
ATTRIBUTE_SYNC_OPTIONS="${ATTRIBUTE_SYNC_OPTIONS:-1}"
ATTRIBUTE_WAIT_TIMEOUT="${ATTRIBUTE_WAIT_TIMEOUT:-21600}"
PROVISION_MISSING_ATTRIBUTES="${PROVISION_MISSING_ATTRIBUTES:-1}"

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

cd "$APP_ROOT"
export PYTHONUNBUFFERED=1

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

echo "=== overnight Magento cleanup/publish ==="
echo "started_utc=$STAMP"
echo "app_root=$APP_ROOT"
echo "connection_id=$MAGENTO_CONNECTION_ID"
echo "dry_run=$DRY_RUN"
echo "log_file=$LOG_FILE"
echo "python=$PYTHON ($("$PYTHON" --version 2>&1 || true))"
echo "run_taxonomy_repair=$RUN_TAXONOMY_REPAIR"
echo "run_attribute_repair=$RUN_ATTRIBUTE_REPAIR"
echo "attribute_bundles=$ATTRIBUTE_BUNDLES"
echo "attribute_fields=$ATTRIBUTE_FIELDS"
echo "attribute_sync_options=$ATTRIBUTE_SYNC_OPTIONS"
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
}

APPLY_ARGS=()
REMOVE_APPLY_ARGS=()
PRUNE_APPLY_ARGS=()
PUBLISH_APPLY_ARGS=()
ENSURE_ATTR_ARGS=()
PUSH_ATTR_ARGS=()

if [[ "$DRY_RUN" == "1" ]]; then
  echo "DRY_RUN=1 — cleanup/publish will preview only"
else
  REMOVE_APPLY_ARGS=(--apply --magento-action hard)
  PRUNE_APPLY_ARGS=(--purge-remote --apply)
  PUBLISH_APPLY_ARGS=(--apply)
  ENSURE_ATTR_ARGS=(--apply)
  PUSH_ATTR_ARGS=(--apply)
fi

# 1) Full catalog pull into magento_catalog_state
run_step "magento_pull_full" \
  "$PYTHON" -m app.jobs.magento_pull \
    --connection-id "$MAGENTO_CONNECTION_ID" \
    --full

# 2) Remove RTA-* products (local plan + live Magento scan)
run_step "remove_rta_products" \
  "$PYTHON" -m app.jobs.remove_channel_products \
    --channel magento \
    --connection-id "$MAGENTO_CONNECTION_ID" \
    --selection sku_filter \
    --sku-filter "RTA-" \
    --scan-remote \
    "${REMOVE_APPLY_ARGS[@]+"${REMOVE_APPLY_ARGS[@]}"}"

# 3) Remove Unassembled products via master filter
run_step "remove_unassembled_products" \
  "$PYTHON" -m app.jobs.remove_channel_products \
    --channel magento \
    --connection-id "$MAGENTO_CONNECTION_ID" \
    --selection master_filter \
    --master-filter "assembled or rta=Unassembled" \
    --scan-remote \
    "${REMOVE_APPLY_ARGS[@]+"${REMOVE_APPLY_ARGS[@]}"}"

# 4) Prune polluted / orphan Magento categories under kitchen hub
run_step "prune_polluted_collections" \
  "$PYTHON" -m app.jobs.prune_polluted_collections \
    --hub-path-slug "$HUB_PATH_SLUG" \
    --magento-connection-id "$MAGENTO_CONNECTION_ID" \
    --channels magento \
    --include-orphans \
    --orphan-tier test \
    --orphan-tier empty_unlinked \
    "${PRUNE_APPLY_ARGS[@]+"${PRUNE_APPLY_ARGS[@]}"}"

# 5) Full Magento publish (taxonomy + products + images); waits for queue
run_step "channel_full_publish" \
  "$PYTHON" -m app.jobs.channel_full_publish \
    --channel magento \
    --magento-connection-id "$MAGENTO_CONNECTION_ID" \
    --wait-timeout "$WAIT_TIMEOUT" \
    --run-pull-after \
    "${PUBLISH_APPLY_ARGS[@]+"${PUBLISH_APPLY_ARGS[@]}"}"

if [[ "$RUN_TAXONOMY_REPAIR" == "1" ]]; then
  LISTING_REPAIR_CMD=(
    "$PYTHON" -m app.jobs.repair_magento_listing_path_targets
    --connection-id "$MAGENTO_CONNECTION_ID"
    --provision-unmatched
  )
  CATEGORY_LINK_REPAIR_CMD=(
    "$PYTHON" -m app.jobs.repair_magento_product_category_links
    --connection-id "$MAGENTO_CONNECTION_ID"
    --all-assigned
  )
  if [[ "$DRY_RUN" == "1" ]]; then
    LISTING_REPAIR_CMD+=(--dry-run)
    CATEGORY_LINK_REPAIR_CMD+=(--dry-run)
  else
    LISTING_REPAIR_CMD+=(--apply)
    CATEGORY_LINK_REPAIR_CMD+=(--apply)
  fi

  # 6) Repair master listing-path targets and provision missing Magento category nodes
  run_step "repair_magento_listing_path_targets" "${LISTING_REPAIR_CMD[@]}"

  # 7) Reconcile live Magento product category links to the repaired taxonomy targets
  run_step "repair_magento_product_category_links" "${CATEGORY_LINK_REPAIR_CMD[@]}"
fi

if [[ "$RUN_ATTRIBUTE_REPAIR" == "1" ]]; then
  ENSURE_CMD=(
    "$PYTHON" -m app.jobs.ensure_magento_spec_attributes
    --connection-id "$MAGENTO_CONNECTION_ID"
  )
  if [[ "$PROVISION_MISSING_ATTRIBUTES" == "1" ]]; then
    ENSURE_CMD+=(--provision-missing)
  fi
  ENSURE_CMD+=("${ENSURE_ATTR_ARGS[@]+"${ENSURE_ATTR_ARGS[@]}"}")

  # Re-push spec/composite fields after the full publish so the overnight
  # service also repairs newer derived attributes and newly provisioned fields.
  PUSH_CMD=(
    "$PYTHON" -m app.jobs.push_magento_attributes
    --connection-id "$MAGENTO_CONNECTION_ID"
    --wait
    --run-worker
    --wait-timeout "$ATTRIBUTE_WAIT_TIMEOUT"
  )
  if [[ -n "$ATTRIBUTE_BUNDLES" ]]; then
    for bundle in $ATTRIBUTE_BUNDLES; do
      PUSH_CMD+=(--bundle "$bundle")
    done
  fi
  if [[ -n "$ATTRIBUTE_FIELDS" ]]; then
    for field in $ATTRIBUTE_FIELDS; do
      PUSH_CMD+=(--field "$field")
    done
  fi
  if [[ "$ATTRIBUTE_SYNC_OPTIONS" == "1" ]]; then
    PUSH_CMD+=(--sync-options)
  fi
  PUSH_CMD+=("${PUSH_ATTR_ARGS[@]+"${PUSH_ATTR_ARGS[@]}"}")

  # 8) Ensure repair/spec attribute mappings exist before the follow-up push
  run_step "ensure_magento_spec_attributes" "${ENSURE_CMD[@]}"

  # 9) Push repaired and derived attributes across the assigned Magento catalog
  run_step "push_magento_repair_attributes" "${PUSH_CMD[@]}"
fi

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"
