<?php

namespace Limb_Chatbot\Includes\Repositories;

use Limb_Chatbot\Includes\Data_Objects\Chat;
use Limb_Chatbot\Includes\Data_Objects\Message;
use Limb_Chatbot\Includes\Services\Collection;


/**
 * Repository class for managing messages related to a specific chat.
 *
 * Provides methods to create, retrieve, delete, and build messages.
 *
 * @since 1.0.0
 */
class Message_Repository {

	/**
	 * Creates a new message record linked to a specific chat.
	 *
	 * @param  array  $data  Message data to create.
	 * @param  Chat  $chat  The Chat object the message belongs to.
	 *
	 * @return Message|null The created message object or null on failure.
	 * @throws \Exception
	 * @since 1.0.0
	 *
	 */
	public function create( $data, Chat $chat ): ?Message {
		$data['chat_uuid'] = $chat->get_uuid();

		return Message::create( $data );
	}

	/**
	 * Retrieves a paginated list of messages associated with the given chat.
	 *
	 * Supports searching by keyword across specified fields.
	 *
	 * @since 1.0.0
	 *
	 * @param Chat  $chat   The Chat object whose messages are being retrieved.
	 * @param array $params {
	 *     Optional. Parameters for filtering and pagination.
	 *
	 *     @type string   $search         Search keyword.
	 *     @type string[] $search_fields  Fields to apply the search against.
	 *     @type int      $per_page       Number of results per page. Default 10.
	 *     @type int      $page           Current page number. Default 1.
	 *     @type string   $orderby        Field to order by. Default 'created_at'.
	 *     @type string   $order          Sort order direction. Accepts 'ASC' or 'DESC'. Default 'desc'.
	 * }
	 *
	 * @return Collection|null A collection of Message objects, or null if none found.
	 */
	public function get_items( Chat $chat, $params ): ?Collection {
		if ( ! empty( $params['search'] ) && ! empty( $params['search_fields'] ) ) {
			foreach ( $params['search_fields'] as $field ) {
				$params["{$field}LIKE"] = "%{$params['search']}%";
			}
		}
		$params['chat_uuid'] = $chat->get_uuid();

		return Message::where( $params, $params['per_page'] ?? 10, $params['page'] ?? 1, $params['orderby'] ?? 'created_at', $params['order'] ?? 'desc' );
	}

	/**
	 * Deletes messages that match the given conditions.
	 *
	 * @since 1.0.0
	 *
	 * @param array $array Conditions to match messages for deletion.
	 *
	 * @return bool True on success, false on failure.
	 */
	public function delete( array $array ): bool {
		return Message::delete( $array );
	}

	/**
	 * Constructs a Message object without persisting it to the database.
	 *
	 * @since 1.0.0
	 *
	 * @param array $data The data for the new message object.
	 *
	 * @return Message The in-memory message object.
	 */
	public function make( array $data ) {
		return Message::make( $data );
	}

	/**
	 * Creates a synthetic text-based assistant message.
	 *
	 * This is a helper for generating a basic structured assistant reply.
	 *
	 * @since 1.0.0
	 *
	 * @param string $value The textual content of the message.
	 *
	 * @return Message The constructed assistant message object.
	 */
	public function make_text_assistant_message($value) {
		// TODO this is kind of ...
		return $this->make([
			'role'    => 'assistant',
			'content' => [
				[
					'type' => 'text',
					'text' => [ 'value' => $value ]
				]
			]
		]);
	}
}