<?php
/**
 * React admin settings screen for Chatbot AI.
 *
 * @package Replyan_AI
 */

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

final class Replyan_AI_Admin {
	private array $pages = array();

	public function register_hooks(): void {
		add_action( 'admin_menu', array( $this, 'add_menu' ) );
		add_action( 'admin_init', array( 'Replyan_AI_Settings', 'maybe_upgrade' ), 5 );
		add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_assets' ) );
		add_action( 'rest_api_init', array( $this, 'register_rest_routes' ) );
		add_action( 'wp_ajax_replyan_ai_save_settings', array( $this, 'save_settings' ) );
		add_action( 'wp_ajax_replyan_ai_get_sessions', array( $this, 'get_sessions' ) );
		add_action( 'wp_ajax_replyan_ai_get_messages', array( $this, 'get_messages' ) );
		add_action( 'wp_ajax_replyan_ai_save_agent', array( $this, 'save_agent' ) );
		add_action( 'wp_ajax_replyan_ai_get_agents', array( $this, 'get_agents' ) );
		add_action( 'wp_ajax_replyan_ai_delete_agent', array( $this, 'delete_agent' ) );
		add_action( 'wp_ajax_replyan_ai_make_default', array( $this, 'make_default_agent' ) );
		add_action( 'wp_ajax_replyan_ai_test_agent', array( $this, 'test_agent' ) );
		add_action( 'admin_footer', array( $this, 'tutorial_menu_target_blank' ) );
	}

	public function add_menu(): void {
		$this->pages[] = add_menu_page(
			__( 'Replyan AI', 'replyan-ai' ),
			__( 'Replyan AI', 'replyan-ai' ),
			'manage_options',
			Replyan_AI_Settings::SETTINGS_PAGE,
			array( $this, 'render_page' ),
			'dashicons-format-chat',
			30
		);

		$this->pages[] = add_submenu_page(
			Replyan_AI_Settings::SETTINGS_PAGE,
			__( 'Dashboard', 'replyan-ai' ),
			__( 'Dashboard', 'replyan-ai' ),
			'manage_options',
			Replyan_AI_Settings::SETTINGS_PAGE,
			array( $this, 'render_page' )
		);

		$this->pages[] = add_submenu_page(
			Replyan_AI_Settings::SETTINGS_PAGE,
			__( 'General', 'replyan-ai' ),
			__( 'General', 'replyan-ai' ),
			'manage_options',
			'replyan-ai-general',
			array( $this, 'render_page' )
		);

		$this->pages[] = add_submenu_page(
			Replyan_AI_Settings::SETTINGS_PAGE,
			__( 'AI Connection', 'replyan-ai' ),
			__( 'AI Connection', 'replyan-ai' ),
			'manage_options',
			'replyan-ai-connection',
			array( $this, 'render_page' )
		);

		$this->pages[] = add_submenu_page(
			Replyan_AI_Settings::SETTINGS_PAGE,
			__( 'Live Chat', 'replyan-ai' ),
			__( 'Live Chat', 'replyan-ai' ),
			'manage_options',
			'replyan-ai-messages',
			array( $this, 'render_page' )
		);

		$this->pages[] = add_submenu_page(
			Replyan_AI_Settings::SETTINGS_PAGE,
			__( 'Agent List', 'replyan-ai' ),
			__( 'Agent List', 'replyan-ai' ),
			'manage_options',
			'replyan-ai-agents',
			array( $this, 'render_page' )
		);

		if ( class_exists( 'Replyan_AI_Leads' ) ) {
			$this->pages[] = add_submenu_page(
				Replyan_AI_Settings::SETTINGS_PAGE,
				__( 'Leads', 'replyan-ai' ),
				__( 'Leads', 'replyan-ai' ),
				'manage_options',
				'replyan-ai-leads',
				array( $this, 'render_page' )
			);
		}

		if ( class_exists( 'Replyan_AI_Forms' ) ) {
			$this->pages[] = add_submenu_page(
				Replyan_AI_Settings::SETTINGS_PAGE,
				__( 'Forms', 'replyan-ai' ),
				__( 'Forms', 'replyan-ai' ),
				'manage_options',
				'replyan-ai-forms',
				array( $this, 'render_page' )
			);
		}

		$this->pages[] = add_submenu_page(
			Replyan_AI_Settings::SETTINGS_PAGE,
			__( 'License', 'replyan-ai' ),
			__( 'License', 'replyan-ai' ),
			'manage_options',
			'replyan-ai-licenses',
			array( $this, 'render_page' )
		);

		$this->pages[] = add_submenu_page(
			Replyan_AI_Settings::SETTINGS_PAGE,
			__( 'Support', 'replyan-ai' ),
			__( 'Support', 'replyan-ai' ),
			'manage_options',
			'replyan-ai-support',
			array( $this, 'render_page' )
		);

		$this->pages[] = add_submenu_page(
			Replyan_AI_Settings::SETTINGS_PAGE,
			__( 'Tutorial', 'replyan-ai' ) . ' <span class="dashicons dashicons-external" style="font-size:15px; margin-top:3px;"></span>',
			__( 'Tutorial', 'replyan-ai' ) . ' <span class="dashicons dashicons-external" style="font-size:15px; margin-top:3px;"></span>',
			'manage_options',
			'https://replyanai.online/tutorial.html'
		);
	}

	/**
	 * Adds target="_blank" to the Tutorial external link in the admin menu.
	 */
	public function tutorial_menu_target_blank(): void {
		?>
		<script type="text/javascript">
			jQuery(document).ready(function($) {
				$('a[href="https://replyanai.online/tutorial.html"]').attr('target', '_blank');
			});
		</script>
		<?php
	}

	public function enqueue_assets( string $hook_suffix ): void {
		if ( ! in_array( $hook_suffix, $this->pages, true ) ) {
			return;
		}

		Replyan_AI_Assets::enqueue( 'replyan-ai-admin', 'src/admin/main.jsx' );

		$active_tab = 'dashboard';
		// phpcs:ignore WordPress.Security.NonceVerification.Recommended
		$page       = sanitize_text_field( wp_unslash( $_GET['page'] ?? '' ) );
		if ( $page === 'replyan-ai-general' ) {
			$active_tab = 'general';
		} elseif ( $page === 'replyan-ai-connection' ) {
			$active_tab = 'ai';
		} elseif ( $page === 'replyan-ai-messages' ) {
			$active_tab = 'messages';
		} elseif ( $page === 'replyan-ai-agents' ) {
			$active_tab = 'agents';
		} elseif ( $page === 'replyan-ai-leads' ) {
			$active_tab = 'leads';
		} elseif ( $page === 'replyan-ai-forms' ) {
			$active_tab = 'forms';
		} elseif ( $page === 'replyan-ai-licenses' ) {
			$active_tab = 'licenses';
		} elseif ( $page === 'replyan-ai-support' ) {
			$active_tab = 'support';
		}

		$raw_expires_at = get_option( 'replyan_ai_license_expires_at', '' );
		$license_status = get_option( 'replyan_ai_license_status', 'inactive' );
		if ( 'active' === $license_status && ! empty( $raw_expires_at ) && time() > strtotime( $raw_expires_at ) ) {
			$license_status = 'expired';
		}

		wp_localize_script(
			'replyan-ai-admin',
			'replyan_ai_admin',
			array(
				'siteUrl'           => site_url(),
				'ajaxUrl'           => admin_url( 'admin-ajax.php' ),
				'pluginUrl'         => REPLYAN_AI_URL,
				'version'           => defined( 'REPLYAN_AI_VERSION' ) ? REPLYAN_AI_VERSION : '1.0.7',
				'saasApiUrl'        => REPLYAN_AI_SAAS_URL,
				'restUrl'           => esc_url_raw( rest_url( 'replyan/v1/admin/' ) ),
				'restNonce'         => wp_create_nonce( 'wp_rest' ),
				'nonce'             => wp_create_nonce( 'replyan_ai_admin_settings' ),
				'messagesNonce'     => wp_create_nonce( 'replyan_ai_admin_messages' ),
				'settings'          => $this->get_safe_settings(),
				'apiKeySaved'          => '' !== trim( (string) ( Replyan_AI_Settings::get()['api_key'] ?? '' ) ),
				'anthropicApiKeySaved' => '' !== trim( (string) ( Replyan_AI_Settings::get()['anthropic_api_key'] ?? '' ) ),
				'geminiApiKeySaved'    => '' !== trim( (string) ( Replyan_AI_Settings::get()['gemini_api_key'] ?? '' ) ),
				'openrouterApiKeySaved'=> '' !== trim( (string) ( Replyan_AI_Settings::get()['openrouter_api_key'] ?? '' ) ),
				'models'               => Replyan_AI_Settings::allowed_models(),
				'activeTab'            => $active_tab,
				'has_agent_takeover'   => class_exists( 'Replyan_AI_Agent_Takeover' ),
				'has_notes'            => class_exists( 'Replyan_AI_Notes' ),
				'has_leads'            => class_exists( 'Replyan_AI_Leads' ),
				'has_forms'            => class_exists( 'Replyan_AI_Forms' ),
				'has_conversation_insights' => class_exists( 'Replyan_Conversation_Insights' ),
				'has_context_awareness' => class_exists( 'Replyan_AI_Context_Awareness' ),
				'has_woocommerce'      => class_exists( 'WooCommerce' ),
				'total_agents'         => count( Replyan_AI_DB::get_agents() ),
				'pm'				   => 'paypal',
				'is_pro'               => Replyan_AI_License::isPro(),
				'license'              => array(
					'key'      		=> get_option( 'replyan_ai_license_key', '' ),
					'status'   		=> $license_status,
					'plan'     		=> get_option( 'replyan_ai_license_plan', 'free' ),
					'features' 		=> get_option( 'replyan_ai_license_features', array() ),
					'expires_at' 	=> get_option( 'replyan_ai_license_expires_at', '' ) ? wp_date( get_option( 'date_format' ) . ' ' . get_option( 'time_format' ), strtotime( get_option( 'replyan_ai_license_expires_at' ) ) ) : '',
				),
			)
		);
	}

	public function save_settings(): void {
		if ( ! current_user_can( 'manage_options' ) ) {
			wp_send_json_error( array( 'message' => __( 'You do not have permission to update these settings.', 'replyan-ai' ) ), 403 );
		}

		check_ajax_referer( 'replyan_ai_admin_settings', 'nonce' );

		// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
		$raw_settings = isset( $_POST['settings'] ) ? wp_unslash( (string) $_POST['settings'] ) : '';
		$settings     = json_decode( $raw_settings, true );

		if ( ! is_array( $settings ) ) {
			wp_send_json_error( array( 'message' => __( 'Invalid settings payload.', 'replyan-ai' ) ), 400 );
		}

		$settings = Replyan_AI_Settings::sanitize( $settings );
		update_option( Replyan_AI_Settings::OPTION_NAME, $settings );

		wp_send_json_success(
			array(
				'settings'             => $this->get_safe_settings(),
				'apiKeySaved'          => '' !== trim( (string) $settings['api_key'] ),
				'anthropicApiKeySaved' => '' !== trim( (string) ( $settings['anthropic_api_key'] ?? '' ) ),
				'geminiApiKeySaved'    => '' !== trim( (string) ( $settings['gemini_api_key'] ?? '' ) ),
				'openrouterApiKeySaved'=> '' !== trim( (string) ( $settings['openrouter_api_key'] ?? '' ) ),
			)
		);
	}

	public function render_page(): void {
		if ( ! current_user_can( 'manage_options' ) ) {
			return;
		}
		?>
		<div class="wrap">
			<div id="replyan-ai-admin-root"></div>
		</div>
		<?php
	}

	private function get_safe_settings(): array {
		$settings = Replyan_AI_Settings::get();
		unset( $settings['api_key'] );
		unset( $settings['anthropic_api_key'] );
		unset( $settings['gemini_api_key'] );
		unset( $settings['openrouter_api_key'] );

		return $settings;
	}

	public function get_sessions(): void {
		if ( ! current_user_can( 'manage_options' ) ) {
			wp_send_json_error( array( 'message' => 'Unauthorized' ), 403 );
		}

		check_ajax_referer( 'replyan_ai_admin_messages', 'nonce' );

		$page = absint( $_POST['page'] ?? 1 ) ?: 1;
		$source_filter = sanitize_text_field( wp_unslash( $_POST['source_filter'] ?? 'all' ) );
		$data = Replyan_AI_DB::get_sessions( $page, 30, $source_filter );

		wp_send_json_success( $data );
	}

	public function get_messages(): void {
		if ( ! current_user_can( 'manage_options' ) ) {
			wp_send_json_error( array( 'message' => 'Unauthorized' ), 403 );
		}

		check_ajax_referer( 'replyan_ai_admin_messages', 'nonce' );

		$session_id = sanitize_text_field( wp_unslash( $_POST['session_id'] ?? '' ) );

		if ( '' === $session_id ) {
			wp_send_json_error( array( 'message' => 'Missing session_id' ), 400 );
		}

		$messages = Replyan_AI_DB::get_messages( $session_id );

		wp_send_json_success( array( 'messages' => $messages ) );
	}

	public function register_rest_routes(): void {
		register_rest_route(
			'replyan/v1/admin',
			'/sessions',
			array(
				'methods'             => 'GET',
				'callback'            => array( $this, 'rest_get_sessions' ),
				'permission_callback' => function() {
					return current_user_can( 'manage_options' );
				},
			)
		);

		register_rest_route(
			'replyan/v1/admin',
			'/messages',
			array(
				'methods'             => 'GET',
				'callback'            => array( $this, 'rest_get_messages' ),
				'permission_callback' => function() {
					return current_user_can( 'manage_options' );
				},
			)
		);

		register_rest_route(
			'replyan/v1/admin',
			'/license/activate',
			array(
				'methods'             => 'POST',
				'callback'            => array( $this, 'rest_license_activate' ),
				'permission_callback' => function() {
					return current_user_can( 'manage_options' );
				},
			)
		);

		register_rest_route(
			'replyan/v1/admin',
			'/license/deactivate',
			array(
				'methods'             => 'POST',
				'callback'            => array( $this, 'rest_license_deactivate' ),
				'permission_callback' => function() {
					return current_user_can( 'manage_options' );
				},
			)
		);

		register_rest_route(
			'replyan/v1/admin',
			'/content-types',
			array(
				'methods'             => 'GET',
				'callback'            => array( $this, 'rest_get_content_types' ),
				'permission_callback' => function() {
					return current_user_can( 'manage_options' );
				},
			)
		);

		register_rest_route(
			'replyan/v1/admin',
			'/content-items',
			array(
				'methods'             => 'GET',
				'callback'            => array( $this, 'rest_get_content_items' ),
				'permission_callback' => function() {
					return current_user_can( 'manage_options' );
				},
			)
		);
	}

	public function rest_license_activate( WP_REST_Request $request ) {
		$license_key = sanitize_text_field( wp_unslash( $request->get_param( 'license_key' ) ?? '' ) );
		
		if ( empty( $license_key ) ) {
			return rest_ensure_response( new WP_Error( 'invalid_key', 'License key is required.', array( 'status' => 400 ) ) );
		}

		$response = wp_remote_post( REPLYAN_AI_SAAS_URL . '/licenses/activate', array(
			'headers' => array( 'Content-Type' => 'application/json' ),
			'body'    => wp_json_encode( array(
				'license_key' => $license_key,
				'site_url'    => get_site_url(),
			) ),
			'timeout' => 15,
		) );

		if ( is_wp_error( $response ) ) {
			return rest_ensure_response( new WP_Error( 'api_error', 'Failed to connect to license server.', array( 'status' => 500 ) ) );
		}

		$body = wp_remote_retrieve_body( $response );
		$data = json_decode( $body, true );
		$status_code = wp_remote_retrieve_response_code( $response );

		if ( $status_code === 200 || $status_code === 201 ) {
			update_option( 'replyan_ai_license_key', $license_key );
			update_option( 'replyan_ai_license_status', 'active' );
			
			$license_data = $data['data'] ?? array();

			$expires_at = sanitize_text_field( wp_unslash( $request->get_param( 'expires_at' ) ?? '' ) );
			if ( empty( $expires_at ) && is_array( $license_data ) ) {
				if ( isset( $license_data['expires_at'] ) ) {
					$expires_at = sanitize_text_field( $license_data['expires_at'] );
				} elseif ( isset( $license_data['subscription']['attributes']['renews_at'] ) ) {
					$expires_at = sanitize_text_field( $license_data['subscription']['attributes']['renews_at'] );
				} elseif ( isset( $license_data['license_key']['expires_at'] ) ) {
					$expires_at  = sanitize_text_field( $license_data['license_key']['expires_at'] );
				}
			}

			$plan_name = sanitize_text_field( wp_unslash( $request->get_param( 'plan_name' ) ?? '' ) );
			if ( empty( $plan_name ) && is_array( $license_data ) ) {
				if ( isset( $license_data['plan_name'] ) ) {
					$plan_name = sanitize_text_field( $license_data['plan_name'] );
				} elseif ( isset( $license_data['meta']['product_name'] ) ) {
					$plan_name = sanitize_text_field( $license_data['meta']['product_name'] );
				}
			}

			update_option( 'replyan_ai_license_expires_at', $expires_at );
			update_option( 'replyan_ai_license_plan', $plan_name );
			
			return rest_ensure_response( array(
				'success' => true,
				'message' => $data['message'] ?? 'License activated successfully',
				'data'    => $license_data,
			) );
		}

		return rest_ensure_response( new WP_Error( 'activation_failed', $data['message'] ?? 'Failed to activate license.', array( 'status' => 400 ) ) );
	}

	public function rest_license_deactivate( WP_REST_Request $request ) {
		$license_key = get_option( 'replyan_ai_license_key', '' );
		
		if ( ! empty( $license_key ) ) {
			wp_remote_post( REPLYAN_AI_SAAS_URL . '/licenses/deactivate', array(
				'headers' => array( 'Content-Type' => 'application/json' ),
				'body'    => wp_json_encode( array(
					'license_key' => $license_key,
					'site_url'    => get_site_url(),
				) ),
				'timeout' => 15,
			) );
		}

		update_option( 'replyan_ai_license_key', '' );
		update_option( 'replyan_ai_license_status', 'inactive' );
		update_option( 'replyan_ai_license_plan', 'free' );
		update_option( 'replyan_ai_license_features', array() );

		return rest_ensure_response( array(
			'success' => true,
			'message' => 'License deactivated successfully',
		) );
	}

	public function rest_get_sessions( WP_REST_Request $request ) {
		$page          = absint( $request->get_param( 'page' ) ?: 1 );
		$per_page      = absint( $request->get_param( 'per_page' ) ?: 10 );
		$source_filter = sanitize_text_field( wp_unslash( $request->get_param( 'source_filter' ) ?? 'all' ) );
		$data          = Replyan_AI_DB::get_sessions( $page, $per_page, $source_filter );

		return rest_ensure_response( array(
			'success' => true,
			'data'    => $data,
		) );
	}

	public function rest_get_messages( WP_REST_Request $request ) {
		$session_id = sanitize_text_field( wp_unslash( $request->get_param( 'session_id' ) ?? '' ) );

		if ( '' === $session_id ) {
			return new WP_Error( 'missing_session', 'Missing session_id', array( 'status' => 400 ) );
		}

		$messages = Replyan_AI_DB::get_messages( $session_id );
		Replyan_AI_DB::reset_unread( $session_id, 'admin' );

		return rest_ensure_response( array(
			'success' => true,
			'data'    => array( 'messages' => $messages ),
		) );
	}

	public function save_agent(): void {
		if ( ! current_user_can( 'manage_options' ) ) {
			wp_send_json_error( array( 'message' => 'Unauthorized' ), 403 );
		}

		check_ajax_referer( 'replyan_ai_admin_settings', 'nonce' );

		// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
		$raw_data = isset( $_POST['agent_data'] ) ? wp_unslash( (string) $_POST['agent_data'] ) : '';
		$data     = json_decode( $raw_data, true );

		if ( ! is_array( $data ) ) {
			wp_send_json_error( array( 'message' => __( 'Invalid agent payload.', 'replyan-ai' ) ), 400 );
		}

		// Enforce free plan limits for new agents
		if ( empty( $data['id'] ) ) {
			if ( ! Replyan_AI_License::isPro() ) {
				$agents_count = count( Replyan_AI_DB::get_agents() );
				if ( $agents_count >= 3 ) {
					wp_send_json_error( array( 'message' => __( 'You have reached the maximum number of agents allowed on the free plan. Please upgrade to Pro to create more.', 'replyan-ai' ) ), 403 );
				}
			}
		}

		$agent_id = Replyan_AI_DB::save_agent( $data );

		if ( $agent_id ) {
			wp_send_json_success( array( 'id' => $agent_id, 'message' => __( 'Agent saved successfully.', 'replyan-ai' ) ) );
		} else {
			wp_send_json_error( array( 'message' => __( 'Failed to save agent.', 'replyan-ai' ) ), 500 );
		}
	}

	public function get_agents(): void {
		if ( ! current_user_can( 'manage_options' ) ) {
			wp_send_json_error( array( 'message' => 'Unauthorized' ), 403 );
		}

		check_ajax_referer( 'replyan_ai_admin_settings', 'nonce' );

		$agents   = Replyan_AI_DB::get_agents();
		$settings = Replyan_AI_Settings::get();
		$default_agent_id = (int) ( $settings['default_agent_id'] ?? 0 );

		// If no default is set, or the default doesn't exist anymore, fall back to the first agent.
		if ( empty( $agents ) ) {
			wp_send_json_success( array( 'agents' => array(), 'default_agent_id' => 0 ) );
		}

		$found_default = false;
		foreach ( $agents as $agent ) {
			if ( (int) $agent['id'] === $default_agent_id ) {
				$found_default = true;
				break;
			}
		}

		if ( ! $found_default ) {
			$default_agent_id = (int) $agents[0]['id'];
			// Auto-update settings with valid default
			$settings['default_agent_id'] = $default_agent_id;
			update_option( Replyan_AI_Settings::OPTION_NAME, $settings );
		}

		wp_send_json_success( array( 'agents' => $agents, 'default_agent_id' => $default_agent_id ) );
	}

	public function delete_agent(): void {
		if ( ! current_user_can( 'manage_options' ) ) {
			wp_send_json_error( array( 'message' => 'Unauthorized' ), 403 );
		}

		check_ajax_referer( 'replyan_ai_admin_settings', 'nonce' );

		$agent_id = isset( $_POST['agent_id'] ) ? (int) $_POST['agent_id'] : 0;

		if ( ! $agent_id ) {
			wp_send_json_error( array( 'message' => __( 'Invalid agent ID.', 'replyan-ai' ) ), 400 );
		}

		$deleted = Replyan_AI_DB::delete_agent( $agent_id );

		if ( $deleted ) {
			wp_send_json_success( array( 'message' => __( 'Agent removed successfully.', 'replyan-ai' ) ) );
		} else {
			wp_send_json_error( array( 'message' => __( 'Failed to remove agent.', 'replyan-ai' ) ), 500 );
		}
	}

	public function make_default_agent(): void {
		if ( ! current_user_can( 'manage_options' ) ) {
			wp_send_json_error( array( 'message' => 'Unauthorized' ), 403 );
		}

		check_ajax_referer( 'replyan_ai_admin_settings', 'nonce' );

		$agent_id = isset( $_POST['agent_id'] ) ? (int) $_POST['agent_id'] : 0;

		if ( ! $agent_id ) {
			wp_send_json_error( array( 'message' => __( 'Invalid agent ID.', 'replyan-ai' ) ), 400 );
		}

		$settings = Replyan_AI_Settings::get();
		$settings['default_agent_id'] = $agent_id;
		update_option( Replyan_AI_Settings::OPTION_NAME, $settings );

		wp_send_json_success( array( 'message' => __( 'Agent set as default.', 'replyan-ai' ) ) );
	}
	public function test_agent(): void {
		if ( ! current_user_can( 'manage_options' ) ) {
			wp_send_json_error( array( 'message' => 'Unauthorized' ), 403 );
		}

		check_ajax_referer( 'replyan_ai_admin_settings', 'nonce' );

		$message = sanitize_textarea_field( wp_unslash( $_POST['message'] ?? '' ) );
		$model = sanitize_text_field( wp_unslash( $_POST['model'] ?? 'gpt-4o' ) );
		$instruction = sanitize_textarea_field( wp_unslash( $_POST['instruction'] ?? '' ) );
		// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
		$temperature = isset( $_POST['temperature'] ) ? (float) wp_unslash( $_POST['temperature'] ) : 0.2;
		// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
		$max_tokens = isset( $_POST['max_tokens'] ) ? absint( wp_unslash( $_POST['max_tokens'] ) ) : 1000;
		// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
		$history_raw = isset( $_POST['history'] ) ? json_decode( wp_unslash( (string) $_POST['history'] ), true ) : array();

		if ( '' === trim( $message ) ) {
			wp_send_json_error( array( 'message' => __( 'Message cannot be empty.', 'replyan-ai' ) ), 400 );
		}

		$base_settings = Replyan_AI_Settings::get();
		
		$provider      = 'openai';
		$key_field     = 'api_key';
		$enabled_field = 'api_key_enabled';

		if ( strpos( $model, 'openrouter/' ) === 0 ) {
			$provider      = 'openrouter';
			$key_field     = 'openrouter_api_key';
			$enabled_field = 'openrouter_api_key_enabled';
			// Strip openrouter/ prefix
			$model = substr( $model, 11 );
		} elseif ( strpos( $model, 'claude' ) === 0 ) {
			$provider      = 'anthropic';
			$key_field     = 'anthropic_api_key';
			$enabled_field = 'anthropic_api_key_enabled';
		} elseif ( strpos( $model, 'gemini' ) === 0 ) {
			$provider      = 'gemini';
			$key_field     = 'gemini_api_key';
			$enabled_field = 'gemini_api_key_enabled';
		}

		if ( empty( $base_settings[ $key_field ] ) ) {
			wp_send_json_error( array( 'message' => sprintf( __( 'The %s API key is not configured yet.', 'replyan-ai' ), ucfirst( $provider ) ) ), 400 );
		}

		if ( '1' !== ( $base_settings[ $enabled_field ] ?? '1' ) ) {
			wp_send_json_error( array( 'message' => sprintf( __( 'The %s connection is currently disabled.', 'replyan-ai' ), ucfirst( $provider ) ) ), 403 );
		}

		$settings = array_merge( $base_settings, array(
			'model'            => $model,
			'system_prompt'    => $instruction,
			'temperature'      => $temperature,
			'max_tokens'       => $max_tokens,
			'skip_agent_fetch' => true,
		) );

		// sanitize history manually for test
		$history = array();
		if ( is_array( $history_raw ) ) {
			foreach ( $history_raw as $msg ) {
				if ( isset( $msg['role'], $msg['content'] ) && in_array( $msg['role'], array( 'user', 'assistant' ), true ) ) {
					$history[] = array(
						'role'    => $msg['role'],
						'content' => sanitize_textarea_field( $msg['content'] ),
					);
				}
			}
		}
		
		// Let's reimplement a simpler curl request here for testing only.
		if ( 'openrouter' === $provider ) {
			$response = Replyan_AI_OpenRouter::send_request( $settings, $message, $history );
		} elseif ( strpos( $model, 'claude' ) === 0 ) {
			$response = Replyan_AI_Anthropic::send_request( $settings, $message, $history );
		} elseif ( strpos( $model, 'gemini' ) === 0 ) {
			$response = Replyan_AI_Gemini::send_request( $settings, $message, $history );
		} else {
			$response = Replyan_AI_OpenAI::send_request( $settings, $message, $history );
		}

		if ( is_wp_error( $response ) ) {
			wp_send_json_error( array( 'message' => $response->get_error_message() ), 500 );
		}

		$status_code = wp_remote_retrieve_response_code( $response );
		$body        = wp_remote_retrieve_body( $response );
		$data        = json_decode( $body, true );

		$reply = '';
		if ( isset( $data['choices'][0]['message']['content'] ) ) {
			$reply = trim( $data['choices'][0]['message']['content'] );
		} elseif ( isset( $data['content'][0]['text'] ) ) {
			$reply = trim( $data['content'][0]['text'] );
		} elseif ( isset( $data['candidates'][0]['content']['parts'][0]['text'] ) ) {
			$reply = trim( $data['candidates'][0]['content']['parts'][0]['text'] );
		}

		if ( 200 !== $status_code || empty( $reply ) ) {
			$error_msg = $data['error']['message'] ?? __( 'Unknown error from provider.', 'replyan-ai' );
			wp_send_json_error( array( 'message' => $error_msg ), $status_code ?: 500 );
		}
		
		wp_send_json_success( array(
			'reply' => $reply,
		) );
	}

	public function rest_get_content_types( WP_REST_Request $request ) {
		$categories = array();
		$post_types = get_post_types( array( 'public' => true ), 'objects' );

		// Exclude attachment
		if ( isset( $post_types['attachment'] ) ) {
			unset( $post_types['attachment'] );
		}

		foreach ( $post_types as $post_type ) {
			$categories[] = array(
				'id'    => $post_type->name,
				'label' => $post_type->labels->name,
			);
		}

		return rest_ensure_response( array(
			'success' => true,
			'data'    => $categories,
		) );
	}

	public function rest_get_content_items( WP_REST_Request $request ) {
		$type   = sanitize_text_field( wp_unslash( $request->get_param( 'type' ) ?? '' ) );
		$search = sanitize_text_field( wp_unslash( $request->get_param( 'search' ) ?? '' ) );
		$page   = max( 1, intval( $request->get_param( 'page' ) ?? 1 ) );
		$limit  = 20;

		if ( empty( $type ) ) {
			return rest_ensure_response( new WP_Error( 'missing_type', 'Post type is required', array( 'status' => 400 ) ) );
		}

		$post_type_obj = get_post_type_object( $type );
		if ( ! $post_type_obj || ! $post_type_obj->public ) {
			return rest_ensure_response( new WP_Error( 'invalid_type', 'Invalid post type', array( 'status' => 400 ) ) );
		}

		$args = array(
			'post_type'      => $type,
			'posts_per_page' => $limit,
			'paged'          => $page,
			'post_status'    => array( 'publish', 'draft', 'pending', 'private' ),
		);

		if ( ! empty( $search ) ) {
			$args['s'] = $search;
		}

		$query = new WP_Query( $args );
		$items = $query->posts;

		$formatted_items = array();
		foreach ( $items as $item ) {
			$status = $item->post_status === 'publish' ? 'Published' : ucfirst( $item->post_status );
			$formatted_items[] = array(
				'id'       => (string) $item->ID,
				'label'    => $item->post_title ? $item->post_title : __( '(No Title)', 'replyan-ai' ),
				'url'      => get_permalink( $item->ID ),
				'postType' => $post_type_obj->labels->name,
				'status'   => $status,
			);
		}

		return rest_ensure_response( array(
			'success' => true,
			'data'    => array(
				'items'       => $formatted_items,
				'has_more'    => $query->max_num_pages > $page,
				'total_items' => $query->found_posts,
			),
		) );
	}
}
