#!/bin/bash

set -euo pipefail

ROOT_DIR="$(pwd)"
TIMESTAMP="$(date +%Y%m%d_%H%M%S)"
REPORT_TXT="$ROOT_DIR/sync_report_$TIMESTAMP.txt"
REPORT_JSON="$ROOT_DIR/sync_report_$TIMESTAMP.json"

DRY_RUN=false
TIMEOUT=60

# Parse args
for arg in "$@"; do
  case $arg in
    --dry-run) DRY_RUN=true ;;
    --timeout=*) TIMEOUT="${arg#*=}" ;;
  esac
done

log() {
  echo -e "$1"
  echo -e "$1" >> "$REPORT_TXT"
}

json_escape() {
  echo "$1" | sed 's/"/\\"/g'
}

run_cmd() {
  if $DRY_RUN; then
    log "🟡 [DRY-RUN] $*"
    return 0
  fi

  timeout "$TIMEOUT" bash -c "$*" >/dev/null 2>&1
}

echo "Repo Sync Report - $(date)" > "$REPORT_TXT"
echo "[" > "$REPORT_JSON"

FIRST=true
SUCCESS=0
FAIL=0
SKIP=0

for dir in */; do
  REPO_PATH="$ROOT_DIR/$dir"
  REPO_NAME=$(basename "$dir")

  STATUS="unknown"
  MESSAGE=""

  log "\n🔹 Processing: $REPO_NAME"

  cd "$REPO_PATH" || { STATUS="fail"; MESSAGE="cannot cd"; ((FAIL++)); continue; }

  if [ ! -d ".git" ]; then
    STATUS="skip"; MESSAGE="not a git repo"; ((SKIP++))
    log "⚠️ Not a git repo"
    continue
  fi

  if ! git remote get-url origin &>/dev/null; then
    STATUS="skip"; MESSAGE="no origin"; ((SKIP++))
    log "⚠️ No origin"
    continue
  fi

  # Detect default branch
  DEFAULT_BRANCH=$(git remote show origin | awk '/HEAD branch/ {print $NF}')
  DEFAULT_BRANCH=${DEFAULT_BRANCH:-main}

  if ! git show-ref --verify --quiet "refs/heads/$DEFAULT_BRANCH"; then
    STATUS="skip"; MESSAGE="no local $DEFAULT_BRANCH"; ((SKIP++))
    log "⚠️ Missing local branch $DEFAULT_BRANCH"
    continue
  fi

  # Check clean working tree
  if ! git diff --quiet || ! git diff --cached --quiet; then
    STATUS="skip"; MESSAGE="uncommitted changes"; ((SKIP++))
    log "⚠️ Uncommitted changes"
    continue
  fi

  CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD)

  if [ "$CURRENT_BRANCH" = "HEAD" ]; then
    STATUS="skip"; MESSAGE="detached HEAD"; ((SKIP++))
    log "⚠️ Detached HEAD"
    continue
  fi

  # Fetch
  if ! run_cmd "git fetch origin --prune"; then
    STATUS="fail"; MESSAGE="fetch failed"; ((FAIL++))
    log "❌ Fetch failed"
    continue
  fi

  # Checkout default branch
  if [ "$CURRENT_BRANCH" != "$DEFAULT_BRANCH" ]; then
    if ! run_cmd "git checkout $DEFAULT_BRANCH"; then
      STATUS="fail"; MESSAGE="checkout failed"; ((FAIL++))
      log "❌ Checkout failed"
      continue
    fi
  fi

  # Rebase safely
  if run_cmd "git rebase origin/$DEFAULT_BRANCH"; then
    STATUS="success"; MESSAGE="rebased"
    log "✅ Rebased onto origin/$DEFAULT_BRANCH"
    ((SUCCESS++))
  else
    git rebase --abort &>/dev/null || true
    STATUS="fail"; MESSAGE="rebase conflict"
    log "❌ Rebase conflict (aborted)"
    ((FAIL++))
  fi

  # Return to original branch
  if [ "$CURRENT_BRANCH" != "$DEFAULT_BRANCH" ]; then
    run_cmd "git checkout $CURRENT_BRANCH"
  fi

  # JSON logging
  ESC_MSG=$(json_escape "$MESSAGE")
  if [ "$FIRST" = true ]; then
    FIRST=false
  else
    echo "," >> "$REPORT_JSON"
  fi

  echo "  {\"repo\":\"$REPO_NAME\",\"status\":\"$STATUS\",\"message\":\"$ESC_MSG\"}" >> "$REPORT_JSON"

done

echo "]" >> "$REPORT_JSON"

log "\n======================================"
log "✅ Success: $SUCCESS"
log "❌ Failed: $FAIL"
log "⚠️ Skipped: $SKIP"
log "📄 TXT Report: $REPORT_TXT"
log "📄 JSON Report: $REPORT_JSON"

echo -e "\nDone."
