<?php

namespace Limb_Chatbot\Includes\Integrations\Slack\Endpoints\Messages;

use Limb_Chatbot\Includes\Exceptions\Exception;
use Limb_Chatbot\Includes\Integrations\Slack\Endpoints\Slack_Endpoint;
use Limb_Chatbot\Includes\Integrations\Slack\Utilities\Messages_Utility;

/**
 * Slack Messages Endpoint
 *
 * Handles message and channel operations with the Slack API including:
 * - Creating channels (conversations.create)
 * - Inviting users (conversations.invite)
 * - Posting messages (chat.postMessage)
 *
 * @package Limb_Chatbot\Includes\Integrations\Slack\Endpoints
 * @since 1.0.0
 */
class Messages_Endpoint extends Slack_Endpoint {

	/**
	 * Messages_Endpoint constructor.
	 *
	 * @param Messages_Utility $utility Utility object containing configuration and context.
	 *
	 * @since 1.0.0
	 */
	public function __construct( Messages_Utility $utility ) {
		parent::__construct( $utility );
	}

	/**
	 * Create a new Slack channel.
	 *
	 * @param string $name       Channel name.
	 * @param bool   $is_private Whether channel is private.
	 *
	 * @return array Channel data with ID.
	 * @throws Exception
	 * @since 1.0.0
	 */
	public function create_channel( string $name, bool $is_private = false ) {
		$http_client = $this->http_client_factory();
		$url         = self::API_BASE_URL . '/conversations.create';

		$response = $http_client->post(
			$url,
			[
				'headers' => $this->get_header(),
				'body'    => json_encode( [
					'name'       => $name,
					'is_private' => $is_private,
				] ),
				'timeout' => $this->utility->get_timeout(),
			]
		);

		$handler = new Messages_Response_Handler( $response, $http_client, $this );
		$result  = $handler->get_body();

		return $result['channel'] ?? [];
	}

	/**
	 * Invite users to a channel.
	 *
	 * @param string $channel_id Channel ID.
	 * @param array  $user_ids   Array of Slack user IDs.
	 *
	 * @return array Response data.
	 * @throws Exception
	 * @since 1.0.0
	 */
	public function invite_users( string $channel_id, array $user_ids ) {
		$http_client = $this->http_client_factory();
		$url         = self::API_BASE_URL . '/conversations.invite';

		$response = $http_client->post(
			$url,
			[
				'headers' => $this->get_header(),
				'body'    => json_encode( [
					'channel' => $channel_id,
					'users'   => implode( ',', $user_ids ),
				] ),
				'timeout' => $this->utility->get_timeout(),
			]
		);

		$handler = new Messages_Response_Handler( $response, $http_client, $this );

		return $handler->get_body();
	}

	/**
	 * Post a message to a channel.
	 *
	 * @param string $channel_id Channel ID.
	 * @param string $text       Message text.
	 * @param array  $blocks     Optional message blocks for rich formatting.
	 *
	 * @return array Response data.
	 * @throws Exception
	 * @since 1.0.0
	 */
	public function post_message( string $channel_id, string $text, array $blocks = [] ) {
		$http_client = $this->http_client_factory();
		$url         = self::API_BASE_URL . '/chat.postMessage';

		$body = [
			'channel' => $channel_id,
			'text'    => $text,
		];

		if ( ! empty( $blocks ) ) {
			$body['blocks'] = $blocks;
		}

		$response = $http_client->post(
			$url,
			[
				'headers' => $this->get_header(),
				'body'    => json_encode( $body ),
				'timeout' => $this->utility->get_timeout(),
			]
		);

		$handler = new Messages_Response_Handler( $response, $http_client, $this );

		return $handler->get_body();
	}

	/**
	 * Get conversation history from a channel.
	 *
	 * @param string      $channel_id Channel ID.
	 * @param string|null $oldest     Oldest timestamp to fetch from.
	 * @param int         $limit      Maximum number of messages to fetch.
	 *
	 * @return array Array of messages.
	 * @throws Exception
	 * @since 1.0.0
	 */
	public function get_history( string $channel_id, ?string $oldest = null, int $limit = 0 ): array {
		$http_client = $this->http_client_factory();
		$url         = self::API_BASE_URL . '/conversations.history';

		$body = [
			'channel' => $channel_id,
		];
		if ( $limit > 0 ) {
			$body['limit'] = $limit;
		}

		if ( ! empty( $oldest ) ) {
			$body['oldest'] = $oldest;
		}

		$response = $http_client->post(
			$url,
			[
				'headers' => $this->get_header(),
				'body'    => json_encode( $body ),
				'timeout' => $this->utility->get_timeout(),
			]
		);

		$handler = new Messages_Response_Handler( $response, $http_client, $this );
		$result  = $handler->get_body();

		return $result['messages'] ?? [];
	}
}

