run_cz() {
  if command -v pnpm >/dev/null 2>&1; then
    pnpm exec cz "$@"
    return $?
  fi

  if command -v bunx >/dev/null 2>&1; then
    bunx cz "$@"
    return $?
  fi

  if command -v yarn >/dev/null 2>&1; then
    yarn cz "$@"
    return $?
  fi

  npx --no-install cz "$@"
}

COMMIT_MSG_FILE="$1"
COMMIT_SOURCE="$2"

# Skip for merge/squash/amend/message-provided commits
case "$COMMIT_SOURCE" in
  merge|squash|commit|message)
    exit 0
    ;;
esac

# Skip if this is our internal commit (avoids recursion)
[ "$CZ_AI_SKIP" = "1" ] && exit 0

# Detect TTY availability without corrupting stdin (subshell test)
if sh -c ': < /dev/tty' 2>/dev/null; then
  # Interactive — full cz-ai flow with prompts, inner commit handles it
  exec < /dev/tty
  run_cz --hook --commit-msg-file "$COMMIT_MSG_FILE"
  CZ_EXIT=$?

  if [ $CZ_EXIT -eq 0 ] && [ -s "$COMMIT_MSG_FILE" ]; then
    CZ_AI_SKIP=1 git commit -F "$COMMIT_MSG_FILE"
  fi

  # Abort the outer git commit (inner one already succeeded, or user cancelled)
  exit 1
else
  # Headless (no TTY, e.g. CI / Claude Code) — use env-driven headless path
  CZ_AI_HEADLESS=1 run_cz --hook --commit-msg-file "$COMMIT_MSG_FILE"
  CZ_EXIT=$?

  if [ $CZ_EXIT -eq 0 ] && [ -s "$COMMIT_MSG_FILE" ]; then
    exit 0
  fi
  exit 1
fi
