<?php

namespace Limb_Chatbot\Includes\Api\V1\Controllers;

use Limb_Chatbot\Includes\Data_Objects\Chat;
use Limb_Chatbot\Includes\Data_Objects\Chatbot_User;
use Limb_Chatbot\Includes\Data_Objects\Chatbot_User_Meta;
use Limb_Chatbot\Includes\Data_Objects\Config;
use Limb_Chatbot\Includes\Exceptions\Error_Codes;
use Limb_Chatbot\Includes\Exceptions\Exception;
use Limb_Chatbot\Includes\Factories\Live_Agent_Service_Factory;
use Limb_Chatbot\Includes\Integrations\Telegram\Telegram;
use Limb_Chatbot\Includes\Services\Collection;
use Limb_Chatbot\Includes\Services\Helper;
use WP_REST_Request;
use WP_REST_Response;
use WP_REST_Server;

/**
 * Live Agent Messages Controller
 *
 * Lightweight REST endpoint for fetching new live agent messages.
 * Supports both polling and webhook modes.
 *
 * @package Limb_Chatbot\Includes\Api\V1\Controllers
 * @since 1.0.0
 */
class Live_Agent_Messages_Controller extends REST_Controller {

	/**
	 * Route base.
	 *
	 * @var string
	 * @since 1.0.0
	 */
	protected $rest_base = 'chats/(?P<chat_uuid>[a-zA-Z0-9\-]+)/live-agent/messages';

	protected $generic_rest_base = 'live-agents';

	/**
	 * Register routes.
	 *
	 * @return void
	 * @since 1.0.0
	 */
	public function register_routes(): void {
		register_rest_route(
			$this->namespace,
			'/' . $this->rest_base,
			[
				[
					'methods'             => WP_REST_Server::READABLE,
					'callback'            => [ $this, 'get_messages' ],
					'permission_callback' => '__return_true',
					'args'                => [
						'chat_uuid' => [
							'required'          => true,
							'type'              => 'string',
							'description'       => __( 'Chat UUID', 'limb-chatbot' ),
							'validate_callback' => function ( $param ) {
								return ! empty( $param );
							},
						],
						'since'     => [
							'required'    => true,
							'type'        => 'string',
							'description' => __( 'Fetch messages since this timestamp', 'limb-chatbot' ),
						],
						'preview'    => [
							'required'    => false,
							'type'        => 'boolean',
							'description' => __( 'Whether to use preview data', 'limb-chatbot' ),
						],
					],
				],
			]
		);
		register_rest_route(
			$this->namespace,
			'/' . $this->generic_rest_base,
			[
				[
					'methods'             => WP_REST_Server::READABLE,
					'callback'            => [ $this, 'get_live_agents' ],
					'permission_callback' => '__return_true',
					'args'                => [
						'config_id' => [
							'required'          => true,
							'type'              => 'integer',
							'description'       => __( 'Config id', 'limb-chatbot' ),
							'sanitize_callback' => 'absint',
						],
					],
				],
			]
		);
	}

	/**
	 * Get new live agent messages.
	 *
	 * Fetches messages that appeared since the last check.
	 * In polling mode, syncs from Slack first.
	 *
	 * @param  WP_REST_Request  $request  Request object.
	 *
	 * @return WP_REST_Response Response object.
	 * @since 1.0.0
	 */
	public function get_messages( $request ): WP_REST_Response {
		try {
			$chat_uuid = $request->get_param( 'chat_uuid' );
			$since     = $request->get_param( 'since' );
			$preview   = $request->get_param( 'preview' ) ?? false;

			// Find chat
			$chat = Chat::find_by_uuid( $chat_uuid );
			if ( ! $chat instanceof Chat ) {
				throw new Exception( Error_Codes::NOT_FOUND, __( 'Chat not found', 'limb-chatbot' ) );
			}

			// Get chatbot utility to check fetch method
			$chatbot              = $chat->get_chatbot();
			$chatbot->set_preview($preview);
			$live_agent_config_id = $chatbot->get_parameter( 'live_agent_config_id' );
			$config               = Config::find( $live_agent_config_id );
			if ( ! $config instanceof Config ) {
				throw new Exception( Error_Codes::NOT_FOUND,
					__( 'The live agent functionality is not configured', 'limb-chatbot' ) );
			}
			$service  = ( new Live_Agent_Service_Factory() )->make( $config );
			$messages = $service->fetch_new_messages( $chatbot, $chat, $since, $config );

			return rest_ensure_response( $messages );
		} catch ( \Exception $e ) {
			Helper::log( $e, __METHOD__ );

			return rest_ensure_response( Helper::get_wp_error( $e ) );
		}
	}

	public function get_live_agents(WP_REST_Request $request){
		try {
			$config_id = $request->get_param('config_id');
			$config = Config::find( $config_id );

			if ( ! $config instanceof Config ) {
				return rest_ensure_response( new Collection() );
			}

			// Get agents by config ID from meta (works for both Slack and Telegram)
			$user_metas = Chatbot_User_Meta::where(['meta_key' => 'live_agent_config_id', 'meta_value' => $config_id]);
			if (!$user_metas->is_empty()){
				$user_ids = array_values($user_metas->pluck('chatbot_user_id'));
			}

			$agents = Chatbot_User::where( [
				'id'   => $user_ids ?? [ - 1 ],
				'type' => Chatbot_User::TYPE_AGENT
			] )->with( ['agent', 'email'] );

			return rest_ensure_response( $agents );
		} catch ( \Exception $e ) {
			Helper::log( $e, __METHOD__ );

			return rest_ensure_response( Helper::get_wp_error( $e ) );
		}
	}
}

