<?php

namespace Limb_Chatbot\Includes\Data_Objects;

use Limb_Chatbot\Includes\Services\Helper;

/**
 * Class Action_Callback
 *
 * Represents a reusable callback that can be attached to actions.
 * Callbacks are executed after action parameters are collected.
 *
 * Examples: HTTP requests, sending emails, Slack notifications, creating posts, etc.
 *
 * @package Limb_Chatbot\Includes\Data_Objects
 * @since 1.0.0
 */
class Action_Callback extends WPDB_Data_Object {

	/**
	 * Callback types constants
	 */
	const TYPE_HTTP_REQUEST = 'http_request';
	const TYPE_EMAIL = 'email';
	const TYPE_SLACK = 'slack';
	const TYPE_TRELLO = 'trello';
	const TYPE_CREATE_POST = 'create_post';
	const TYPE_UPDATE_POST = 'update_post';
	const TYPE_WEBHOOK = 'webhook';
	const TYPE_CUSTOM = 'custom';

	/**
	 * Status constants
	 */
	const STATUS_ACTIVE = 1;
	const STATUS_INACTIVE = 0;

	/**
	 * Database table name
	 */
	const TABLE_NAME = 'lbaic_action_callbacks';

	/**
	 * Fillable fields
	 */
	const FILLABLE = [
		'id',
		'action_id',
		'name',
		'title',
		'description',
		'type',
		'config',
		'order',
		'is_required',
		'status',
	];

	/**
	 * @var int|null Callback ID
	 */
	public ?int $id = null;

	/**
	 * @var string Unique callback name (e.g., generate_voucher_http)
	 */
	public string $name;

	/**
	 * @var string Human-readable title
	 */
	public string $title;

	/**
	 * @var string|null Callback description
	 */
	public ?string $description = null;

	/**
	 * @var string Callback type (http_request, email, slack, etc.)
	 */
	public string $type;
	/**
	 * @var int Status (1=active, 0=inactive)
	 */
	public int $status = self::STATUS_ACTIVE;
	/**
	 * @var int|null Action ID this callback belongs to
	 */
	public ?int $action_id = null;
	/**
	 * @var int Order of execution for this callback
	 */
	public int $order = 0;
	/**
	 * @var int Is this callback required for the action to proceed?
	 */
	public int $is_required = 1;
	/**
	 * @var array Callback configuration (method, URL, headers, body, etc.)
	 */
	public array $config = [];

	/**
	 * Constructor
	 *
	 * @param  mixed|null  $instance  Instance data for hydration
	 */
	public function __construct( $instance = null ) {
		// Decode JSON fields before hydration
		if ( is_array( $instance ) ) {
			if ( ! empty( $instance['config'] ) && $this->isJson( $instance['config'] ) ) {
				$instance['config'] = Helper::maybe_json_decode( $instance['config'] );
			}
		}
		parent::__construct( $instance );
	}

	/**
	 * Find callback by name
	 *
	 * @param  string  $name  Callback name
	 *
	 * @return static|null
	 */
	public static function find_by_name( string $name ): ?self {
		return self::where( [ 'name' => $name ] )->first() ?? null;
	}

	/**
	 * Get callback name
	 *
	 * @return string
	 */
	public function get_name(): string {
		return $this->name;
	}

	/**
	 * Set callback name
	 *
	 * @param  string  $name
	 *
	 * @return void
	 */
	public function set_name( string $name ): void {
		$this->name = $name;
	}

	/**
	 * Get callback title
	 *
	 * @return string
	 */
	public function get_title(): string {
		return $this->title;
	}

	/**
	 * Set callback title
	 *
	 * @param  string  $title
	 *
	 * @return void
	 */
	public function set_title( string $title ): void {
		$this->title = $title;
	}

	/**
	 * Get callback description
	 *
	 * @return string|null
	 */
	public function get_description(): ?string {
		return $this->description;
	}

	/**
	 * Set callback description
	 *
	 * @param  string|null  $description
	 *
	 * @return void
	 */
	public function set_description( ?string $description ): void {
		$this->description = $description;
	}

	/**
	 * Get callback type
	 *
	 * @return string
	 */
	public function get_type(): string {
		return $this->type;
	}

	/**
	 * Set callback type
	 *
	 * @param  string  $type
	 *
	 * @return void
	 */
	public function set_type( string $type ): void {
		$this->type = $type;
	}

	/**
	 * Get callback configuration
	 *
	 * @return array
	 */
	public function get_config(): array {
		return $this->config;
	}

	/**
	 * Set callback configuration
	 *
	 * @param  array  $config
	 *
	 * @return void
	 */
	public function set_config( array $config ): void {
		$this->config = $config;
	}

	/**
	 * Get status
	 *
	 * @return int
	 */
	public function get_status(): int {
		return $this->status;
	}

	/**
	 * Set status
	 *
	 * @param  int  $status
	 *
	 * @return void
	 */
	public function set_status( int $status ): void {
		$this->status = $status;
	}

	/**
	 * Check if callback is active
	 *
	 * @return bool
	 */
	public function is_active(): bool {
		return $this->status === self::STATUS_ACTIVE;
	}

	/**
	 * Get action_id
	 *
	 * @return int|null
	 */
	public function get_action_id(): ?int {
		return $this->action_id;
	}

	/**
	 * Set action_id
	 *
	 * @param  int|null  $action_id
	 *
	 * @return void
	 */
	public function set_action_id( ?int $action_id ): void {
		$this->action_id = $action_id;
	}

	/**
	 * Get order
	 *
	 * @return int
	 */
	public function get_order(): int {
		return $this->order;
	}

	/**
	 * Set order
	 *
	 * @param  int  $order
	 *
	 * @return void
	 */
	public function set_order( int $order ): void {
		$this->order = $order;
	}

	/**
	 * Get is_required
	 *
	 * @return int
	 */
	public function get_is_required(): int {
		return $this->is_required;
	}

	/**
	 * Set is_required
	 *
	 * @param  int  $is_required
	 *
	 * @return void
	 */
	public function set_is_required( int $is_required ): void {
		$this->is_required = $is_required;
	}
}
