#!/bin/sh
# Exit on any error
set -e

# Get only staged *.ts files
STAGED_TS_FILES=$(git diff --cached --name-only --diff-filter=ACMR | grep '\.ts$' || true)

# Check if there are any staged .ts files
if [ -z "$STAGED_TS_FILES" ]; then
  echo "No staged .ts files to format"
  exit 0
fi

# Store the hash of staged changes to detect modifications
STAGED_HASH=$(git diff --cached | sha256sum | cut -d' ' -f1)

# Save list of partially staged files
PARTIALLY_STAGED=$(git diff --name-only)

# Stash unstaged changes to preserve working directory
# --keep-index keeps staged changes in working tree
git stash push --quiet --keep-index --message "pre-commit-stash" || true
STASHED=$?

# Run formatter only on staged .ts files
echo "$STAGED_TS_FILES" | xargs pnpm dlx ultracite fix
FORMAT_EXIT_CODE=$?

# Restore working directory state
if [ $STASHED -eq 0 ]; then
  # Re-stage the formatted .ts files
  echo "$STAGED_TS_FILES" | while IFS= read -r file; do
    if [ -f "$file" ]; then
      git add "$file"
    fi
  done
  
  # Restore unstaged changes
  git stash pop --quiet || true
  
  # Restore partial staging if files were partially staged
  if [ -n "$PARTIALLY_STAGED" ]; then
    for file in $PARTIALLY_STAGED; do
      if [ -f "$file" ] && echo "$STAGED_TS_FILES" | grep -q "^$file$"; then
        # File was partially staged - need to unstage the unstaged parts
        git restore --staged "$file" 2>/dev/null || true
        git add -p "$file" < /dev/null 2>/dev/null || git add "$file"
      fi
    done
  fi
else
  # No stash was created, just re-add the formatted files
  echo "$STAGED_TS_FILES" | while IFS= read -r file; do
    if [ -f "$file" ]; then
      git add "$file"
    fi
  done
fi

# Check if staged files actually changed
NEW_STAGED_HASH=$(git diff --cached | sha256sum | cut -d' ' -f1)
if [ "$STAGED_HASH" != "$NEW_STAGED_HASH" ]; then
  echo "✨ Files formatted by Ultracite"
fi

exit $FORMAT_EXIT_CODE
