<?php
/**
 * Rollback execution helper for admin autonomy.
 *
 * @package Niwa_AI
 */

defined( 'ABSPATH' ) || exit;

class Niwa_AI_Admin_Autonomy_Rollback_Runner {
	private $store;
	private $executor;
	/** @var array<string,callable> */
	private $callbacks;

	public function __construct( $store, $executor, $callbacks = array() ) {
		$this->store     = $store;
		$this->executor  = $executor;
		$this->callbacks = is_array( $callbacks ) ? $callbacks : array();
	}

	public function run() {
		if ( ! $this->call( 'acquire_lock', array( 'rollback_run', 120 ), false ) ) {
			return 'Rollback je vec u toku. Sacekaj da se prethodni rollback zavrsi.';
		}

		try {
			$run = $this->store ? $this->store->get_latest_completed_run_for_rollback() : array();
			if ( empty( $run ) ) {
				return 'Nema dostupnog uspesnog run-a za rollback.';
			}

			$this->call( 'send_typing_indicator_from_run', array( $run ) );

			$result = $this->executor ? $this->executor->rollback_run( $run ) : array(
				'success' => false,
				'error'   => 'Rollback executor nije dostupan.',
			);
			if ( empty( $result['success'] ) ) {
				$error = isset( $result['error'] ) ? (string) $result['error'] : 'Rollback failed.';
				if ( $this->store ) {
					$this->store->mark_rolled_back( $run['id'], 'failed', $error );
				}
				return 'Rollback nije uspeo za run #' . intval( $run['id'] ) . '. Razlog: ' . $error;
			}

			if ( $this->store ) {
				$this->store->mark_rolled_back( $run['id'], 'completed', '' );
			}

			return sprintf(
				"Rollback run #%d zavrsen.\n%s",
				intval( $run['id'] ),
				isset( $result['summary'] ) ? (string) $result['summary'] : ''
			);
		} finally {
			$this->call( 'release_lock', array( 'rollback_run' ) );
		}
	}

	private function call( $name, $args = array(), $default = null ) {
		return Niwa_AI_Admin_Autonomy_Callbacks::call( $this->callbacks, $name, $args, $default );
	}
}
