<?php
/**
 * Trigger Execution Exception Class
 *
 * Exception for trigger-related failures.
 *
 * @package Sequensy
 * @since 2.0.0
 */

declare(strict_types=1);

namespace Sequensy\Exceptions;

use Throwable;

// If this file is called directly, abort.
if ( ! defined( 'WPINC' ) ) {
	die;
}

/**
 * Class TriggerException
 *
 * Thrown when a workflow trigger fails to execute or evaluate.
 */
class TriggerException extends SequensyException {

	/**
	 * Trigger type that failed.
	 *
	 * @var string
	 */
	protected string $trigger_type;

	/**
	 * Workflow ID.
	 *
	 * @var int|null
	 */
	protected ?int $workflow_id;

	/**
	 * Constructor.
	 *
	 * @param string         $message      Error message.
	 * @param string         $trigger_type Trigger type that failed.
	 * @param int|null       $workflow_id  Workflow ID.
	 * @param array          $context      Additional context data.
	 * @param Throwable|null $previous     Previous exception.
	 */
	public function __construct(
		string $message = '',
		string $trigger_type = '',
		?int $workflow_id = null,
		array $context = array(),
		?Throwable $previous = null
	) {
		$this->trigger_type = $trigger_type;
		$this->workflow_id  = $workflow_id;

		// Ensure trigger info is in context.
		$context['trigger_type'] = $trigger_type;
		if ( null !== $workflow_id ) {
			$context['workflow_id'] = $workflow_id;
		}

		parent::__construct( $message, 0, $context, $previous );
	}

	/**
	 * Get trigger type.
	 *
	 * @return string Trigger type.
	 */
	public function get_trigger_type(): string {
		return $this->trigger_type;
	}

	/**
	 * Get workflow ID.
	 *
	 * @return int|null Workflow ID.
	 */
	public function get_workflow_id(): ?int {
		return $this->workflow_id;
	}

	/**
	 * Get the WP_Error code for this exception.
	 *
	 * @return string Error code.
	 */
	protected function get_error_code(): string {
		return 'sequensy_trigger_error';
	}

	/**
	 * Create exception for filter evaluation failure.
	 *
	 * @param string   $trigger_type Trigger type.
	 * @param string   $message      Error message.
	 * @param int|null $workflow_id  Workflow ID.
	 * @param array    $context      Additional context.
	 * @return static Exception instance.
	 */
	public static function filterEvaluationFailed(
		string $trigger_type,
		string $message,
		?int $workflow_id = null,
		array $context = array()
	): static {
		$context['failure_type'] = 'filter_evaluation';

		return new static(
			sprintf( 'Filter evaluation failed for trigger %s: %s', $trigger_type, $message ),
			$trigger_type,
			$workflow_id,
			$context
		);
	}

	/**
	 * Create exception for trigger handler not found.
	 *
	 * @param string $trigger_type Trigger type.
	 * @param array  $context      Additional context.
	 * @return static Exception instance.
	 */
	public static function handlerNotFound( string $trigger_type, array $context = array() ): static {
		$context['failure_type'] = 'handler_not_found';

		return new static(
			sprintf( 'No handler registered for trigger type: %s', $trigger_type ),
			$trigger_type,
			null,
			$context
		);
	}

	/**
	 * Create exception for trigger context build failure.
	 *
	 * @param string   $trigger_type Trigger type.
	 * @param string   $message      Error message.
	 * @param int|null $workflow_id  Workflow ID.
	 * @param array    $context      Additional context.
	 * @return static Exception instance.
	 */
	public static function contextBuildFailed(
		string $trigger_type,
		string $message,
		?int $workflow_id = null,
		array $context = array()
	): static {
		$context['failure_type'] = 'context_build';

		return new static(
			sprintf( 'Failed to build context for trigger %s: %s', $trigger_type, $message ),
			$trigger_type,
			$workflow_id,
			$context
		);
	}
}
