I honestly do not see how this can work, there are multiple issues.
1) the function does not include a
global $post; statement, without this the line
$query->the_post(); does not do what is expected and when you call
get_the_ID() this will return the post ID of whatever page the function is called on and not the post ID for the current iteration of the post.
2) The query does not include a meta query looking for only posts that have not been updated, a value you are attempting to set here
update_post_meta(get_the_ID(), 'state_update_complete', '1');, note my previous comment about the fact that
get_the_ID() is likely not returning the correct value, but that aside, without a meta query to exclude posts that have been updated already on a site with many, many posts (could be hundreds or thousands depending on the hosting) to process then it will likely time out and will start at the beginning each time it is run rather than picking up where it left off. Setting this meta value has no purpose if you do not then check the value in the query.
2) the call to
$acf_value = get_field('admin_theme'); will return the value for the current post and not the post of the current iteration of the loop for the same reason mentioned in #1
Welcome to the Advanced Custom Fields community forum.
Browse through ideas, snippets of code, questions and answers between fellow ACF users
Helping others is a great way to earn karma, gain badges and help ACF development!