<?php

namespace VendorTasksDokanClickUp\VendorIntegration;

use VendorTasksDokanClickUp\API\ClickUpClient;

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

/**
 * Trigger Action
 *
 * Collapses the repeated boilerplate across all trigger modules:
 * get task_id → get client → run callback → log WP_Error.
 *
 * @since 1.4.0
 * @package VendorTasksDokanClickUp
 * @subpackage VendorIntegration
 */
class TriggerAction {

	/**
	 * VendorTaskState instance.
	 *
	 * @var VendorTaskState
	 */
	private VendorTaskState $task_state;

	/**
	 * Constructor.
	 *
	 * @param VendorTaskState|null $task_state Injected for testing; uses default if null.
	 */
	public function __construct( ?VendorTaskState $task_state = null ) {
		$this->task_state = $task_state ?? new VendorTaskState();
	}

	/**
	 * Add a comment to the vendor's ClickUp task if one exists.
	 *
	 * Convenience wrapper around run_if_task_exists for the common add-comment pattern.
	 *
	 * @param int    $vendor_id   Vendor user ID.
	 * @param string $comment     Comment text (plain text — no HTML).
	 * @param string $log_context Prefix for error log entries.
	 * @return bool True on success; false if no task exists or the request failed.
	 */
	public function add_comment( int $vendor_id, string $comment, string $log_context = '' ): bool {
		return $this->run_if_task_exists(
			$vendor_id,
			fn( $client, $task_id ) => $client->add_task_comment( $task_id, $comment ),
			$log_context
		);
	}

	/**
	 * Run $callback only if the vendor has a ClickUp task and the client is available.
	 *
	 * The callback receives the ClickUpClient instance and the task ID string.
	 * Any WP_Error returned by the callback is logged and causes this method to return false.
	 *
	 * @param int      $vendor_id   Vendor user ID.
	 * @param callable $callback    fn(ClickUpClient $client, string $task_id): mixed|\WP_Error.
	 * @param string   $log_context Prefix prepended to error messages in the log.
	 * @return bool True if callback ran and returned non-WP_Error; false otherwise.
	 */
	public function run_if_task_exists( int $vendor_id, callable $callback, string $log_context = '' ): bool {
		$task_id = $this->task_state->get_task_id( $vendor_id );
		if ( empty( $task_id ) ) {
			return false;
		}

		$client = vendor_tasks_dokan_clickup()->get_clickup_client();
		if ( ! $client ) {
			return false;
		}

		$result = $callback( $client, $task_id );

		if ( is_wp_error( $result ) ) {
			$msg = $log_context
				? sprintf( '%s: %s', rtrim( $log_context, ':' ), $result->get_error_message() )
				: $result->get_error_message();
			vendor_tasks_dokan_clickup()->log( $msg, 'error' );
			return false;
		}

		return true;
	}
}
