<?php

namespace Limb_Chatbot\Includes\Repositories;

use Limb_Chatbot\Includes\Data_Objects\Chatbot;
use Limb_Chatbot\Includes\Database_Strategies\WPDB;
use Limb_Chatbot\Includes\Services\Data_Object_Collection;


/**
 * Repository for performing operations on Chatbot data objects.
 *
 * @since 1.0.0
 */
class Chatbot_Repository {

	/**
	 * The associated Chatbot Meta repository instance.
	 *
	 * @since 1.0.0
	 *
	 * @var Chatbot_Meta_Repository
	 */
	public Chatbot_Meta_Repository $meta_repository;

	/**
	 * Chatbot_Repository constructor.
	 *
	 * @since 1.0.0
	 */
	public function __construct() {
		$this->meta_repository = new Chatbot_Meta_Repository();
	}


	/**
	 * Creates a new chatbot record.
	 *
	 * @since 1.0.0
	 *
	 * @param array $data Chatbot attributes.
	 * @return Chatbot|null The created Chatbot instance or null on failure.
	 */
	public function create( array $data ): ?Chatbot {
		return Chatbot::create( $data );
	}

	/**
	 * Updates an existing chatbot by ID.
	 *
	 * @since 1.0.0
	 *
	 * @param int   $chatbot_id ID of the chatbot to update.
	 * @param array $data       Updated chatbot attributes.
	 * @return Chatbot|null The updated Chatbot instance or null on failure.
	 */
	public function update( int $chatbot_id, array $data ): ?Chatbot {
		return Chatbot::update( ['id' => $chatbot_id], $data );
	}

	/**
	 * Retrieves a chatbot by ID or UUID.
	 *
	 * @since 1.0.0
	 *
	 * @param int|string $chatbot_id ID or UUID of the chatbot.
	 * @param array|null $params     Optional query params (currently unused).
	 * @return Chatbot|null The found chatbot or null if not found.
	 */
	public function get_item( $chatbot_id, ?array $params = [] ): ?Chatbot {
		return is_int( $chatbot_id ) ? Chatbot::find( $chatbot_id ) : Chatbot::find_by_uuid( $chatbot_id );
	}

	/**
	 * Retrieves a collection of chatbots filtered by the given parameters.
	 *
	 * @since 1.0.0
	 *
	 * @param array|null $params Filter parameters.
	 * @return Data_Object_Collection A collection of Chatbot instances.
	 */
	public function get_items( ?array $params = [] ): Data_Object_Collection {
		return Chatbot::where( $params );
	}

	/**
	 * Retrieves a chatbot by UUID or returns an empty chatbot object if null.
	 *
	 * @since 1.0.0
	 *
	 * @param string|null $chatbot_uuid UUID of the chatbot.
	 * @return Chatbot The found Chatbot or an empty instance.
	 */
	public function get_by_uuid( ?string $chatbot_uuid = null ): Chatbot {
		return $chatbot_uuid ? Chatbot::find_by_uuid( $chatbot_uuid ) : Chatbot::make();
	}

	/**
	 * Fetch frontend chatbot settings in one wp_options query.
	 *
	 * @param  string[]  $keys  Setting key suffixes (without lbaic.utilities.chatbot. prefix).
	 *
	 * @return array<string,mixed>
	 * @since 2.0.0
	 */
	public function get_settings( array $keys ): array {
		$wpdb = WPDB::instance()->get_wpdb();

		$placeholders = implode( ', ', array_fill( 0, count( $keys ), '%s' ) );
		$options_table = $wpdb->options;
		$rows = $wpdb->get_results(
			$wpdb->prepare(
				"SELECT option_name, option_value FROM {$options_table} WHERE option_name IN ({$placeholders})",
				$keys
			),
			ARRAY_A
		);
		$map = [];
		foreach ( $rows as $row ) {
			$option_name  = isset( $row['option_name'] ) ? (string) $row['option_name'] : '';
			$option_value = $row['option_value'] ?? null;

			if ( '' === $option_name ) {
				continue;
			}
			$map[$option_name] = $option_value;
		}

		return $map;
	}
}
