#!/bin/zsh

# ╔═══════════════════════════════════════════════════════════════════╗
# ║  ws-check: Build & test only the npm workspaces with dirty files  ║
# ║  Usage: wscheck [-b [base_branch]]                                ║
# ║                                                                   ║
# ║  Flags:                                                           ║
# ║    -b, --branch [base]  Check all files changed on the current    ║
# ║                         branch vs base (default: main or master)  ║
# ║                                                                   ║
# ║  🤖 Written by a human + AI pair programming sesh (GitHub         ║
# ║     Copilot CLI, Claude). Don't trust it blindly — read the       ║
# ║     code, break the code, own the code. Down with black boxes.    ║
# ║                                                                   ║
# ║  "The street finds its own uses for things." — William Gibson     ║
# ╚═══════════════════════════════════════════════════════════════════╝

wscheck() {
  local branch_mode=0
  local base_branch=""

  # Parse arguments
  while [[ $# -gt 0 ]]; do
    case "$1" in
      -b|--branch)
        branch_mode=1
        if [[ -n "$2" && "$2" != -* ]]; then
          base_branch="$2"
          shift
        fi
        shift
        ;;
      *)
        echo "\033[31m✗ Unknown argument: $1\033[0m"
        echo "Usage: wscheck [-b|--branch [base_branch]]"
        return 1
        ;;
    esac
  done

  local root=$(git rev-parse --show-toplevel 2>/dev/null)
  if [[ $? -ne 0 ]]; then
    echo "\033[31m✗ Not in a git repository\033[0m"
    return 1
  fi

  if [[ ! -f "$root/package.json" ]]; then
    echo "\033[31m✗ No package.json found at repo root\033[0m"
    return 1
  fi

  # Get workspace patterns from root package.json
  local ws_patterns=("${(@f)$(jq -r '.workspaces // .workspaces.packages // [] | .[]' "$root/package.json" 2>/dev/null)}")
  if [[ ${#ws_patterns[@]} -eq 0 ]]; then
    echo "\033[31m✗ No workspaces defined in package.json\033[0m"
    return 1
  fi

  # Get changed files (branch mode or dirty mode)
  local changed_files=()
  if [[ $branch_mode -eq 1 ]]; then
    # Auto-detect default branch if not specified
    if [[ -z "$base_branch" ]]; then
      if git -C "$root" show-ref --verify --quiet refs/heads/main; then
        base_branch="main"
      elif git -C "$root" show-ref --verify --quiet refs/heads/master; then
        base_branch="master"
      else
        echo "\033[31m✗ Could not detect base branch (no main or master found). Specify one: wscheck -b \033[0m"
        return 1
      fi
    fi

    local merge_base=$(git -C "$root" merge-base "$base_branch" HEAD 2>/dev/null)
    if [[ $? -ne 0 ]]; then
      echo "\033[31m✗ Could not find merge-base with '$base_branch' — does that branch exist?\033[0m"
      return 1
    fi

    changed_files=("${(@f)$(git -C "$root" diff --name-only "$merge_base"..HEAD)}")
    echo "\033[2m🌿 Branch mode: comparing against $base_branch ($(echo $merge_base | cut -c1-8))\033[0m"
    echo ""
  else
    # Staged + unstaged + untracked
    changed_files=("${(@f)$(git -C "$root" status --porcelain | awk '{print $NF}')}")
  fi
  if [[ ${#changed_files[@]} -eq 0 || -z "${changed_files[1]}" ]]; then
    echo "\033[32m✓ No changed files — nothing to do 🎉\033[0m"
    return 0
  fi

  # Resolve workspace directories from glob patterns
  local ws_dirs=()
  for pattern in $ws_patterns; do
    for dir in $root/$~pattern(/N); do
      if [[ -f "$dir/package.json" ]]; then
        ws_dirs+=("${dir#$root/}")
      fi
    done
  done

  # Find which workspaces have changes
  local affected_ws=()
  for ws in $ws_dirs; do
    for file in $changed_files; do
      if [[ "$file" == "$ws"/* ]]; then
        affected_ws+=("$ws")
        break
      fi
    done
  done

  if [[ ${#affected_ws[@]} -eq 0 ]]; then
    echo "\033[32m✓ Changes don't affect any workspace — all good 👍\033[0m"
    return 0
  fi

  echo "\033[1;36m⚡ Affected workspaces:\033[0m"
  for ws in $affected_ws; do
    local ws_name=$(jq -r '.name // "unnamed"' "$root/$ws/package.json")
    echo "   \033[33m◆\033[0m $ws_name \033[2m($ws)\033[0m"
  done
  echo ""

  # Spinner frames
  local spin_frames=('⠋' '⠙' '⠹' '⠸' '⠼' '⠴' '⠦' '⠧' '⠇' '⠏')
  local failures=()
  local successes=()
  local total=${#affected_ws[@]}
  local current=0

  _spin_run() {
    local label="$1"
    local cmd="$2"
    local logfile=$(mktemp)
    local pid frame_idx

    eval "$cmd" > "$logfile" 2>&1 &
    pid=$!
    frame_idx=0

    while kill -0 $pid 2>/dev/null; do
      printf "\r   ${spin_frames[$((frame_idx % ${#spin_frames[@]} + 1))]} \033[1m%s\033[0m" "$label"
      frame_idx=$((frame_idx + 1))
      sleep 0.08
    done

    wait $pid
    local exit_code=$?

    if [[ $exit_code -eq 0 ]]; then
      printf "\r   \033[32m✓\033[0m %s\033[K\n" "$label"
    else
      printf "\r   \033[31m✗\033[0m %s\033[K\n" "$label"
    fi

    # Return log content via global var (zsh workaround)
    _spin_log=$(cat "$logfile")
    rm -f "$logfile"
    return $exit_code
  }

  for ws in $affected_ws; do
    current=$((current + 1))
    local ws_name=$(jq -r '.name // "unnamed"' "$root/$ws/package.json")
    local has_build=$(jq -r '.scripts.build // empty' "$root/$ws/package.json")
    local has_test=$(jq -r '.scripts.test // empty' "$root/$ws/package.json")

    echo "\033[1m[$current/$total]\033[0m \033[1;35m$ws_name\033[0m"

    # Build
    if [[ -n "$has_build" ]]; then
      _spin_run "build" "cd '$root/$ws' && npm run build"
      if [[ $? -ne 0 ]]; then
        failures+=("\033[31m✗ $ws_name → build\033[0m\n\033[2m$_spin_log\033[0m")
        echo ""
        continue
      fi
    else
      echo "   \033[2m⊘ no build script, skipping\033[0m"
    fi

    # Test
    if [[ -n "$has_test" ]]; then
      _spin_run "test" "cd '$root/$ws' && npm test"
      if [[ $? -ne 0 ]]; then
        failures+=("\033[31m✗ $ws_name → test\033[0m\n\033[2m$_spin_log\033[0m")
        echo ""
        continue
      fi
    else
      echo "   \033[2m⊘ no test script, skipping\033[0m"
    fi

    successes+=("$ws_name")
    echo ""
  done

  # Summary
  echo "\033[1m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\033[0m"
  if [[ ${#successes[@]} -gt 0 ]]; then
    echo "\033[32m✓ Passed: ${#successes[@]}/$total\033[0m"
  fi

  if [[ ${#failures[@]} -gt 0 ]]; then
    echo "\033[31m✗ Failed: ${#failures[@]}/$total\033[0m"
    echo ""
    echo "\033[1;31m╭─ Failures ─────────────────────────────╮\033[0m"
    for fail in $failures; do
      echo ""
      echo -e "  $fail"
    done
    echo ""
    echo "\033[1;31m╰────────────────────────────────────────╯\033[0m"
    return 1
  else
    echo "\033[32m\n🎉 All workspaces passed! Ship it! 🚀\033[0m"
    return 0
  fi
}