<?php

declare(strict_types=1);

namespace Drupal\flowdrop_interrupt\Entity;

use Drupal\Core\Entity\ContentEntityInterface;
use Drupal\Core\Entity\EntityChangedInterface;
use Drupal\flowdrop_interrupt\Enum\InterruptStatus;
use Drupal\flowdrop_interrupt\Enum\InterruptType;
use Drupal\user\EntityOwnerInterface;

/**
 * Interface for FlowDrop Interrupt entities.
 *
 * Interrupt entities store requests for human input during workflow execution.
 * They persist the interrupt state, allowing workflows to pause and resume
 * after user interaction.
 *
 * @internal This class is not part of the public API and may change without notice.
 */
interface FlowDropInterruptInterface extends ContentEntityInterface, EntityChangedInterface, EntityOwnerInterface {

  /**
   * Gets the workflow ID.
   *
   * @return string
   *   The workflow ID.
   */
  public function getWorkflowId(): string;

  /**
   * Sets the workflow ID.
   *
   * @param string $workflow_id
   *   The workflow ID.
   *
   * @return $this
   */
  public function setWorkflowId(string $workflow_id): static;

  /**
   * Gets the pipeline/execution ID.
   *
   * @return string|null
   *   The pipeline ID or NULL if not associated with a pipeline.
   */
  public function getPipelineId(): ?string;

  /**
   * Sets the pipeline/execution ID.
   *
   * @param string|null $pipeline_id
   *   The pipeline ID.
   *
   * @return $this
   */
  public function setPipelineId(?string $pipeline_id): static;

  /**
   * Gets the playground session ID.
   *
   * @return int|null
   *   The session ID or NULL if not associated with a session.
   */
  public function getSessionId(): ?int;

  /**
   * Sets the playground session ID.
   *
   * @param int|null $session_id
   *   The session ID.
   *
   * @return $this
   */
  public function setSessionId(?int $session_id): static;

  /**
   * Gets the node ID that triggered the interrupt.
   *
   * @return string
   *   The node ID.
   */
  public function getNodeId(): string;

  /**
   * Sets the node ID.
   *
   * @param string $node_id
   *   The node ID.
   *
   * @return $this
   */
  public function setNodeId(string $node_id): static;

  /**
   * Gets the interrupt type.
   *
   * @return \Drupal\flowdrop_interrupt\Enum\InterruptType
   *   The interrupt type.
   */
  public function getType(): InterruptType;

  /**
   * Sets the interrupt type.
   *
   * @param \Drupal\flowdrop_interrupt\Enum\InterruptType $type
   *   The interrupt type.
   *
   * @return $this
   */
  public function setType(InterruptType $type): static;

  /**
   * Gets the interrupt status.
   *
   * @return \Drupal\flowdrop_interrupt\Enum\InterruptStatus
   *   The interrupt status.
   */
  public function getStatus(): InterruptStatus;

  /**
   * Sets the interrupt status.
   *
   * @param \Drupal\flowdrop_interrupt\Enum\InterruptStatus $status
   *   The interrupt status.
   *
   * @return $this
   */
  public function setStatus(InterruptStatus $status): static;

  /**
   * Gets the display message.
   *
   * @return string
   *   The message to display to the user.
   */
  public function getMessage(): string;

  /**
   * Sets the display message.
   *
   * @param string $message
   *   The message.
   *
   * @return $this
   */
  public function setMessage(string $message): static;

  /**
   * Gets the JSON Schema for input validation.
   *
   * @return array<string, mixed>
   *   The JSON Schema or empty array if not set.
   */
  public function getSchema(): array;

  /**
   * Sets the JSON Schema for input validation.
   *
   * @param array<string, mixed> $schema
   *   The JSON Schema.
   *
   * @return $this
   */
  public function setSchema(array $schema): static;

  /**
   * Gets the options for choice-type interrupts.
   *
   * @return array<int, array{value: string, label: string, description?: string}>
   *   The options array.
   */
  public function getOptions(): array;

  /**
   * Sets the options for choice-type interrupts.
   *
   * @param array<int, array{value: string, label: string, description?: string}> $options
   *   The options array.
   *
   * @return $this
   */
  public function setOptions(array $options): static;

  /**
   * Gets the default value.
   *
   * @return mixed
   *   The default value.
   */
  public function getDefaultValue(): mixed;

  /**
   * Sets the default value.
   *
   * @param mixed $value
   *   The default value.
   *
   * @return $this
   */
  public function setDefaultValue(mixed $value): static;

  /**
   * Gets the user's response data.
   *
   * @return mixed
   *   The response data or NULL if not resolved.
   */
  public function getResponseData(): mixed;

  /**
   * Sets the user's response data.
   *
   * @param mixed $data
   *   The response data.
   *
   * @return $this
   */
  public function setResponseData(mixed $data): static;

  /**
   * Gets the execution context for resuming the workflow.
   *
   * @return array<string, mixed>
   *   The execution context.
   */
  public function getContext(): array;

  /**
   * Sets the execution context.
   *
   * @param array<string, mixed> $context
   *   The execution context.
   *
   * @return $this
   */
  public function setContext(array $context): static;

  /**
   * Gets the expiration timestamp.
   *
   * @return int|null
   *   The expiration timestamp or NULL if no expiration.
   */
  public function getExpires(): ?int;

  /**
   * Sets the expiration timestamp.
   *
   * @param int|null $timestamp
   *   The expiration timestamp.
   *
   * @return $this
   */
  public function setExpires(?int $timestamp): static;

  /**
   * Gets the user ID who resolved the interrupt.
   *
   * @return int|null
   *   The user ID or NULL if not resolved.
   */
  public function getResolvedBy(): ?int;

  /**
   * Sets the user ID who resolved the interrupt.
   *
   * @param int|null $user_id
   *   The user ID.
   *
   * @return $this
   */
  public function setResolvedBy(?int $user_id): static;

  /**
   * Gets the resolution timestamp.
   *
   * @return int|null
   *   The timestamp or NULL if not resolved.
   */
  public function getResolvedAt(): ?int;

  /**
   * Sets the resolution timestamp.
   *
   * @param int|null $timestamp
   *   The timestamp.
   *
   * @return $this
   */
  public function setResolvedAt(?int $timestamp): static;

  /**
   * Gets the creation timestamp.
   *
   * @return int
   *   The creation timestamp.
   */
  public function getCreatedTime(): int;

  /**
   * Gets the last changed timestamp.
   *
   * @return int
   *   The changed timestamp.
   */
  public function getChangedTime(): int;

  /**
   * Checks if the interrupt is pending.
   *
   * @return bool
   *   TRUE if pending.
   */
  public function isPending(): bool;

  /**
   * Checks if the interrupt is resolved.
   *
   * @return bool
   *   TRUE if resolved.
   */
  public function isResolved(): bool;

  /**
   * Checks if the interrupt has expired.
   *
   * @return bool
   *   TRUE if expired.
   */
  public function isExpired(): bool;

  /**
   * Resolves the interrupt with the given response data.
   *
   * @param mixed $response_data
   *   The user's response.
   * @param int|null $user_id
   *   The user ID who resolved it.
   *
   * @return $this
   */
  public function resolve(mixed $response_data, ?int $user_id = NULL): static;

  /**
   * Cancels the interrupt.
   *
   * @return $this
   */
  public function cancel(): static;

  /**
   * Marks the interrupt as expired.
   *
   * @return $this
   */
  public function expire(): static;

  /**
   * Converts the interrupt to an array for API responses.
   *
   * @return array<string, mixed>
   *   The interrupt data as an array.
   */
  public function toApiArray(): array;

}
