<?php
/**
 * Main plugin class.
 *
 * @package OpenRouterSiteChatbotByJayanta
 */

defined( 'ABSPATH' ) || exit;

/**
 * Registers settings, admin UI, AJAX endpoints, and frontend widget.
 */
class ORSC_Plugin {
	/**
	 * Singleton instance.
	 *
	 * @var self|null
	 */
	private static $instance = null;

	/**
	 * Return singleton.
	 *
	 * @return self
	 */
	public static function instance() {
		if ( null === self::$instance ) {
			self::$instance = new self();
		}

		return self::$instance;
	}

	/**
	 * Activation defaults.
	 *
	 * @return void
	 */
	public static function activate() {
		if ( ! get_option( ORSC_OPTION ) ) {
			add_option( ORSC_OPTION, self::default_settings(), '', false );
		}
	}

	/**
	 * Deactivation cleanup.
	 *
	 * @return void
	 */
	public static function deactivate() {
		wp_clear_scheduled_hook( 'orsc_rebuild_index' );
	}

	/**
	 * Default settings.
	 *
	 * @return array
	 */
	private static function default_settings() {
		return array(
			'enabled'            => 1,
			'api_key'            => '',
			'model'              => 'openai/gpt-4o-mini',
			'bot_name'           => __( 'Site Assistant', 'jayanta-ai-site-chatbot-with-openrouter' ),
			'welcome_message'    => __( 'Hi! Ask me anything about this website.', 'jayanta-ai-site-chatbot-with-openrouter' ),
			'placeholder'        => __( 'Type your question...', 'jayanta-ai-site-chatbot-with-openrouter' ),
			'primary_color'      => '#2563eb',
			'post_types'         => array( 'post', 'page' ),
			'index_limit'        => 200,
			'max_sources'        => 5,
			'context_characters' => 7000,
			'max_tokens'         => 600,
			'temperature'        => 0.2,
			'rate_limit'         => 20,
			'log_chats'          => 1,
		);
	}

	/**
	 * Constructor.
	 */
	private function __construct() {
		add_action( 'admin_menu', array( $this, 'admin_menu' ) );
		add_action( 'admin_init', array( $this, 'register_settings' ) );
		add_action( 'admin_enqueue_scripts', array( $this, 'admin_assets' ) );
		add_action( 'wp_enqueue_scripts', array( $this, 'frontend_assets' ) );
		add_action( 'wp_footer', array( $this, 'render_widget' ) );
		add_action( 'wp_ajax_orsc_chat', array( $this, 'ajax_chat' ) );
		add_action( 'wp_ajax_nopriv_orsc_chat', array( $this, 'ajax_chat' ) );
		add_action( 'wp_ajax_orsc_rebuild_index', array( $this, 'ajax_rebuild_index' ) );
		add_action( 'save_post', array( $this, 'schedule_index_rebuild' ), 10, 3 );
		add_action( 'orsc_rebuild_index', array( $this, 'rebuild_index' ) );
		add_action( 'update_option_' . ORSC_OPTION, array( $this, 'settings_updated' ), 10, 3 );
		add_filter( 'plugin_action_links_' . plugin_basename( ORSC_PLUGIN_FILE ), array( $this, 'settings_link' ) );
	}

	/**
	 * Settings with defaults.
	 *
	 * @return array
	 */
	private function settings() {
		$settings = get_option( ORSC_OPTION, array() );
		return wp_parse_args( is_array( $settings ) ? $settings : array(), self::default_settings() );
	}

	/**
	 * Add settings link.
	 *
	 * @param array $links Plugin links.
	 * @return array
	 */
	public function settings_link( $links ) {
		array_unshift( $links, '<a href="' . esc_url( admin_url( 'options-general.php?page=orsc-chatbot' ) ) . '">' . esc_html__( 'Settings', 'jayanta-ai-site-chatbot-with-openrouter' ) . '</a>' );
		return $links;
	}

	/**
	 * Register admin page.
	 *
	 * @return void
	 */
	public function admin_menu() {
		add_options_page(
			__( 'Smart AI Chatbot with OpenRouter', 'jayanta-ai-site-chatbot-with-openrouter' ),
			__( 'Smart AI Chatbot', 'jayanta-ai-site-chatbot-with-openrouter' ),
			'manage_options',
			'orsc-chatbot',
			array( $this, 'render_admin_page' )
		);
	}

	/**
	 * Register settings.
	 *
	 * @return void
	 */
	public function register_settings() {
		register_setting(
			'orsc_settings',
			ORSC_OPTION,
			array(
				'type'              => 'array',
				'sanitize_callback' => array( $this, 'sanitize_settings' ),
				'default'           => self::default_settings(),
			)
		);
	}

	/**
	 * Sanitize settings.
	 *
	 * @param array $value Raw settings.
	 * @return array
	 */
	public function sanitize_settings( $value ) {
		$current = $this->settings();
		$value   = is_array( $value ) ? $value : array();
		$api_key = isset( $value['api_key'] ) ? trim( wp_unslash( (string) $value['api_key'] ) ) : '';

		if ( '' === $api_key && ! empty( $current['api_key'] ) ) {
			$api_key = $current['api_key'];
		}

		$post_types = isset( $value['post_types'] ) && is_array( $value['post_types'] ) ? array_map( 'sanitize_key', wp_unslash( $value['post_types'] ) ) : array( 'post', 'page' );
		$public     = get_post_types( array( 'public' => true ), 'names' );
		$post_types = array_values( array_intersect( $post_types, $public ) );
		$primary_color = isset( $value['primary_color'] ) ? sanitize_hex_color( wp_unslash( (string) $value['primary_color'] ) ) : '#2563eb';

		return array(
			'enabled'            => empty( $value['enabled'] ) ? 0 : 1,
			'api_key'            => sanitize_text_field( $api_key ),
			'model'              => isset( $value['model'] ) ? sanitize_text_field( wp_unslash( (string) $value['model'] ) ) : 'openai/gpt-4o-mini',
			'bot_name'           => isset( $value['bot_name'] ) ? sanitize_text_field( wp_unslash( (string) $value['bot_name'] ) ) : __( 'Site Assistant', 'jayanta-ai-site-chatbot-with-openrouter' ),
			'welcome_message'    => isset( $value['welcome_message'] ) ? sanitize_text_field( wp_unslash( (string) $value['welcome_message'] ) ) : '',
			'placeholder'        => isset( $value['placeholder'] ) ? sanitize_text_field( wp_unslash( (string) $value['placeholder'] ) ) : '',
			'primary_color'      => $primary_color ? $primary_color : '#2563eb',
			'post_types'         => $post_types ? $post_types : array( 'post', 'page' ),
			'index_limit'        => min( 1000, max( 10, absint( isset( $value['index_limit'] ) ? $value['index_limit'] : 200 ) ) ),
			'max_sources'        => min( 10, max( 1, absint( isset( $value['max_sources'] ) ? $value['max_sources'] : 5 ) ) ),
			'context_characters' => min( 16000, max( 1000, absint( isset( $value['context_characters'] ) ? $value['context_characters'] : 7000 ) ) ),
			'max_tokens'         => min( 2000, max( 150, absint( isset( $value['max_tokens'] ) ? $value['max_tokens'] : 600 ) ) ),
			'temperature'        => min( 1, max( 0, (float) ( isset( $value['temperature'] ) ? $value['temperature'] : 0.2 ) ) ),
			'rate_limit'         => min( 200, max( 1, absint( isset( $value['rate_limit'] ) ? $value['rate_limit'] : 20 ) ) ),
			'log_chats'          => empty( $value['log_chats'] ) ? 0 : 1,
		);
	}

	/**
	 * Enqueue admin assets.
	 *
	 * @param string $hook Current admin hook.
	 * @return void
	 */
	public function admin_assets( $hook ) {
		if ( 'settings_page_orsc-chatbot' !== $hook ) {
			return;
		}

		wp_enqueue_style( 'orsc-admin', ORSC_PLUGIN_URL . 'assets/admin.css', array(), ORSC_VERSION );
		wp_enqueue_script( 'orsc-admin', ORSC_PLUGIN_URL . 'assets/admin.js', array(), ORSC_VERSION, true );
		wp_localize_script(
			'orsc-admin',
			'ORSC_ADMIN',
			array(
				'ajaxUrl' => admin_url( 'admin-ajax.php' ),
				'nonce'   => wp_create_nonce( 'orsc_admin' ),
				'i18n'    => array(
					'rebuilding' => __( 'Rebuilding...', 'jayanta-ai-site-chatbot-with-openrouter' ),
					'done'       => __( 'Index rebuilt.', 'jayanta-ai-site-chatbot-with-openrouter' ),
					'error'      => __( 'Unable to rebuild the index.', 'jayanta-ai-site-chatbot-with-openrouter' ),
				),
			)
		);
	}

	/**
	 * Enqueue frontend assets.
	 *
	 * @return void
	 */
	public function frontend_assets() {
		$settings = $this->settings();

		if ( is_admin() || empty( $settings['enabled'] ) ) {
			return;
		}

		wp_enqueue_style( 'orsc-frontend', ORSC_PLUGIN_URL . 'assets/frontend.css', array(), ORSC_VERSION );
		wp_enqueue_script( 'orsc-frontend', ORSC_PLUGIN_URL . 'assets/frontend.js', array(), ORSC_VERSION, true );
		wp_localize_script(
			'orsc-frontend',
			'ORSC_CHATBOT',
			array(
				'ajaxUrl'       => admin_url( 'admin-ajax.php' ),
				'nonce'         => wp_create_nonce( 'orsc_chat' ),
				'botName'       => $settings['bot_name'],
				'welcome'       => $settings['welcome_message'],
				'placeholder'   => $settings['placeholder'],
				'primaryColor'  => $settings['primary_color'],
				'historyKey'    => 'orsc_chat_history_' . md5( home_url( '/' ) ),
				'strings'       => array(
					'open'     => __( 'Open chat', 'jayanta-ai-site-chatbot-with-openrouter' ),
					'close'    => __( 'Close chat', 'jayanta-ai-site-chatbot-with-openrouter' ),
					'send'     => __( 'Send', 'jayanta-ai-site-chatbot-with-openrouter' ),
					'thinking' => __( 'Thinking...', 'jayanta-ai-site-chatbot-with-openrouter' ),
					'error'    => __( 'Sorry, I could not answer right now.', 'jayanta-ai-site-chatbot-with-openrouter' ),
				),
			)
		);
	}

	/**
	 * Render frontend widget shell.
	 *
	 * @return void
	 */
	public function render_widget() {
		$settings = $this->settings();

		if ( is_admin() || empty( $settings['enabled'] ) ) {
			return;
		}
		?>
		<div id="orsc-chatbot" class="orsc-chatbot" data-open="false">
			<button type="button" class="orsc-chatbot__toggle" aria-label="<?php esc_attr_e( 'Open chat', 'jayanta-ai-site-chatbot-with-openrouter' ); ?>">
				<span class="orsc-chatbot__bubble-icon">AI</span>
			</button>
			<section class="orsc-chatbot__panel" aria-live="polite">
				<header class="orsc-chatbot__header">
					<strong><?php echo esc_html( $settings['bot_name'] ); ?></strong>
					<button type="button" class="orsc-chatbot__close" aria-label="<?php esc_attr_e( 'Close chat', 'jayanta-ai-site-chatbot-with-openrouter' ); ?>">x</button>
				</header>
				<div class="orsc-chatbot__messages"></div>
				<form class="orsc-chatbot__form">
					<textarea class="orsc-chatbot__input" rows="1" maxlength="700" required></textarea>
					<button type="submit" class="orsc-chatbot__send"><?php esc_html_e( 'Send', 'jayanta-ai-site-chatbot-with-openrouter' ); ?></button>
				</form>
			</section>
		</div>
		<?php
	}

	/**
	 * Handle visitor chat.
	 *
	 * @return void
	 */
	public function ajax_chat() {
		check_ajax_referer( 'orsc_chat', 'nonce' );

		$settings = $this->settings();

		if ( empty( $settings['enabled'] ) ) {
			wp_send_json_error( array( 'message' => __( 'The chatbot is currently disabled.', 'jayanta-ai-site-chatbot-with-openrouter' ) ), 403 );
		}

		if ( ! $this->rate_limit_ok( $settings ) ) {
			wp_send_json_error( array( 'message' => __( 'Please slow down and try again later.', 'jayanta-ai-site-chatbot-with-openrouter' ) ), 429 );
		}

		$question    = isset( $_POST['message'] ) ? sanitize_textarea_field( wp_unslash( $_POST['message'] ) ) : '';
		$history_raw = isset( $_POST['history'] ) ? sanitize_textarea_field( wp_unslash( $_POST['history'] ) ) : '';
		$history     = $history_raw ? json_decode( $history_raw, true ) : array();

		if ( '' === $question || strlen( $question ) > 700 ) {
			wp_send_json_error( array( 'message' => __( 'Please enter a shorter question.', 'jayanta-ai-site-chatbot-with-openrouter' ) ), 400 );
		}

		$history = $this->sanitize_history( $history );
		$index   = new ORSC_Content_Index( $settings );
		$sources = $index->search( $question );

		if ( empty( $sources ) ) {
			$sources = $index->live_search( $question );
		}

		if ( empty( $sources ) ) {
			wp_send_json_success(
				array(
					'answer'  => __( 'I could not find a matching page or product in this site content. Please try a more specific product name or contact the site owner.', 'jayanta-ai-site-chatbot-with-openrouter' ),
					'sources' => array(),
				)
			);
		}

		$messages = array_merge(
			$history,
			array(
				array(
					'role'    => 'user',
					'content' => $question,
				),
			)
		);

		$prompt = $this->system_prompt( $index->context_text( $sources ) );
		$client = new ORSC_OpenRouter_Client( $settings['api_key'], $settings['model'], $settings['max_tokens'], $settings['temperature'] );
		$result = $client->chat( $prompt, $messages );

		if ( is_wp_error( $result ) ) {
			wp_send_json_error( array( 'message' => $result->get_error_message() ), $this->error_status( $result ) );
		}

		$this->add_log( $question, $sources, $result );

		wp_send_json_success(
			array(
				'answer'  => wp_kses_post( $result['answer'] ),
				'sources' => $this->public_sources( $sources ),
			)
		);
	}

	/**
	 * Rebuild content index from admin.
	 *
	 * @return void
	 */
	public function ajax_rebuild_index() {
		check_ajax_referer( 'orsc_admin', 'nonce' );

		if ( ! current_user_can( 'manage_options' ) ) {
			wp_send_json_error( array( 'message' => __( 'Permission denied.', 'jayanta-ai-site-chatbot-with-openrouter' ) ), 403 );
		}

		$index = $this->rebuild_index();
		wp_send_json_success(
			array(
				'count'    => isset( $index['doc_count'] ) ? absint( $index['doc_count'] ) : 0,
				'builtAt'  => isset( $index['built_at'] ) ? $index['built_at'] : '',
				'message'  => __( 'Content index rebuilt successfully.', 'jayanta-ai-site-chatbot-with-openrouter' ),
			)
		);
	}

	/**
	 * Schedule index rebuild after public content changes.
	 *
	 * @param int     $post_id Post ID.
	 * @param WP_Post $post Post object.
	 * @param bool    $update Whether this is an existing post.
	 * @return void
	 */
	public function schedule_index_rebuild( $post_id, $post, $update ) {
		if ( wp_is_post_revision( $post_id ) || 'publish' !== $post->post_status ) {
			return;
		}

		if ( ! wp_next_scheduled( 'orsc_rebuild_index' ) ) {
			wp_schedule_single_event( time() + 60, 'orsc_rebuild_index' );
		}
	}

	/**
	 * Rebuild the content index after settings changes.
	 *
	 * @param array  $old_value Previous settings.
	 * @param array  $value New settings.
	 * @param string $option Option name.
	 * @return void
	 */
	public function settings_updated( $old_value, $value, $option ) {
		unset( $option );

		$old_post_types = isset( $old_value['post_types'] ) && is_array( $old_value['post_types'] ) ? $old_value['post_types'] : array();
		$new_post_types = isset( $value['post_types'] ) && is_array( $value['post_types'] ) ? $value['post_types'] : array();

		sort( $old_post_types );
		sort( $new_post_types );

		if (
			$old_post_types !== $new_post_types ||
			absint( isset( $old_value['index_limit'] ) ? $old_value['index_limit'] : 0 ) !== absint( isset( $value['index_limit'] ) ? $value['index_limit'] : 0 )
		) {
			$this->rebuild_index();
		}
	}

	/**
	 * Rebuild index.
	 *
	 * @return array
	 */
	public function rebuild_index() {
		$index = new ORSC_Content_Index( $this->settings() );
		return $index->rebuild();
	}

	/**
	 * Create system prompt.
	 *
	 * @param string $context Site context.
	 * @return string
	 */
	private function system_prompt( $context ) {
		return "You are a helpful website assistant for " . get_bloginfo( 'name' ) . ". Answer visitor questions using only the site content below. If the answer is not present, say that you could not find it in the site content and suggest contacting the site owner. Be concise, accurate, and friendly. Do not invent policies, prices, product details, or contact information. When useful, mention the page title you used.\n\nSITE CONTENT:\n" . $context;
	}

	/**
	 * Sanitize short chat history.
	 *
	 * @param mixed $history Raw history.
	 * @return array
	 */
	private function sanitize_history( $history ) {
		if ( ! is_array( $history ) ) {
			return array();
		}

		$clean = array();
		foreach ( array_slice( $history, -6 ) as $message ) {
			if ( empty( $message['role'] ) || empty( $message['content'] ) ) {
				continue;
			}

			$role = 'assistant' === $message['role'] ? 'assistant' : 'user';
			$text = wp_html_excerpt( sanitize_textarea_field( (string) $message['content'] ), 700, '' );

			if ( '' !== $text ) {
				$clean[] = array(
					'role'    => $role,
					'content' => $text,
				);
			}
		}

		return $clean;
	}

	/**
	 * Check rate limit by visitor IP.
	 *
	 * @param array $settings Settings.
	 * @return bool
	 */
	private function rate_limit_ok( $settings ) {
		$ip     = isset( $_SERVER['REMOTE_ADDR'] ) ? sanitize_text_field( wp_unslash( $_SERVER['REMOTE_ADDR'] ) ) : 'unknown';
		$key    = 'orsc_rate_' . md5( $ip . wp_salt( 'nonce' ) );
		$count  = absint( get_transient( $key ) );
		$limit  = absint( $settings['rate_limit'] );

		if ( $count >= $limit ) {
			return false;
		}

		set_transient( $key, $count + 1, HOUR_IN_SECONDS );
		return true;
	}

	/**
	 * Public source fields.
	 *
	 * @param array $sources Sources.
	 * @return array
	 */
	private function public_sources( $sources ) {
		$public = array();

		foreach ( $sources as $source ) {
			$public[] = array(
				'title' => $source['title'],
				'url'   => $source['url'],
			);
		}

		return $public;
	}

	/**
	 * Log compact chat metadata.
	 *
	 * @param string $question Question.
	 * @param array  $sources Sources.
	 * @param array  $result Result.
	 * @return void
	 */
	private function add_log( $question, $sources, $result ) {
		$settings = $this->settings();

		if ( empty( $settings['log_chats'] ) ) {
			return;
		}

		$logs   = get_option( ORSC_LOG_OPTION, array() );
		$logs   = is_array( $logs ) ? $logs : array();
		$logs[] = array(
			'time'        => current_time( 'mysql' ),
			'question'    => wp_html_excerpt( $question, 180, '' ),
			'source_count' => count( $sources ),
			'tokens'      => isset( $result['usage']['total_tokens'] ) ? absint( $result['usage']['total_tokens'] ) : 0,
		);

		update_option( ORSC_LOG_OPTION, array_slice( $logs, -30 ), false );
	}

	/**
	 * Convert WP_Error status into an HTTP status.
	 *
	 * @param WP_Error $error Error.
	 * @return int
	 */
	private function error_status( $error ) {
		$data = $error->get_error_data();
		return isset( $data['status'] ) ? absint( $data['status'] ) : 500;
	}

	/**
	 * Render admin settings page.
	 *
	 * @return void
	 */
	public function render_admin_page() {
		if ( ! current_user_can( 'manage_options' ) ) {
			wp_die( esc_html__( 'You do not have permission to access this page.', 'jayanta-ai-site-chatbot-with-openrouter' ) );
		}

		$settings   = $this->settings();
		$index      = get_option( ORSC_INDEX_OPTION, array() );
		$logs       = get_option( ORSC_LOG_OPTION, array() );
		$post_types = get_post_types( array( 'public' => true ), 'objects' );
		?>
		<div class="wrap orsc-admin">
			<h1><?php esc_html_e( 'Smart AI Chatbot with OpenRouter', 'jayanta-ai-site-chatbot-with-openrouter' ); ?></h1>
			<p class="description"><?php esc_html_e( 'A floating AI assistant that answers visitors from your published WordPress content.', 'jayanta-ai-site-chatbot-with-openrouter' ); ?></p>

			<div class="orsc-admin__grid">
				<section class="orsc-admin__panel">
					<h2><?php esc_html_e( 'Settings', 'jayanta-ai-site-chatbot-with-openrouter' ); ?></h2>
					<form method="post" action="options.php">
						<?php settings_fields( 'orsc_settings' ); ?>
						<table class="form-table" role="presentation">
							<tr>
								<th scope="row"><?php esc_html_e( 'Enable chatbot', 'jayanta-ai-site-chatbot-with-openrouter' ); ?></th>
								<td><label><input type="checkbox" name="<?php echo esc_attr( ORSC_OPTION ); ?>[enabled]" value="1" <?php checked( $settings['enabled'], 1 ); ?>> <?php esc_html_e( 'Show the floating chatbot on the public site.', 'jayanta-ai-site-chatbot-with-openrouter' ); ?></label></td>
							</tr>
							<tr>
								<th scope="row"><label for="orsc-api-key"><?php esc_html_e( 'OpenRouter API key', 'jayanta-ai-site-chatbot-with-openrouter' ); ?></label></th>
								<td>
									<input id="orsc-api-key" type="password" class="regular-text" name="<?php echo esc_attr( ORSC_OPTION ); ?>[api_key]" value="" autocomplete="off" placeholder="<?php echo esc_attr( $settings['api_key'] ? __( 'Saved. Leave blank to keep current key.', 'jayanta-ai-site-chatbot-with-openrouter' ) : __( 'sk-or-v1-...', 'jayanta-ai-site-chatbot-with-openrouter' ) ); ?>">
									<p class="description"><?php esc_html_e( 'Stored server-side. The key is never sent to visitor browsers.', 'jayanta-ai-site-chatbot-with-openrouter' ); ?></p>
								</td>
							</tr>
							<tr>
								<th scope="row"><label for="orsc-model"><?php esc_html_e( 'OpenRouter model', 'jayanta-ai-site-chatbot-with-openrouter' ); ?></label></th>
								<td><input id="orsc-model" type="text" class="regular-text" name="<?php echo esc_attr( ORSC_OPTION ); ?>[model]" value="<?php echo esc_attr( $settings['model'] ); ?>"></td>
							</tr>
							<tr>
								<th scope="row"><label for="orsc-bot-name"><?php esc_html_e( 'Bot name', 'jayanta-ai-site-chatbot-with-openrouter' ); ?></label></th>
								<td><input id="orsc-bot-name" type="text" class="regular-text" name="<?php echo esc_attr( ORSC_OPTION ); ?>[bot_name]" value="<?php echo esc_attr( $settings['bot_name'] ); ?>"></td>
							</tr>
							<tr>
								<th scope="row"><label for="orsc-welcome"><?php esc_html_e( 'Welcome message', 'jayanta-ai-site-chatbot-with-openrouter' ); ?></label></th>
								<td><input id="orsc-welcome" type="text" class="large-text" name="<?php echo esc_attr( ORSC_OPTION ); ?>[welcome_message]" value="<?php echo esc_attr( $settings['welcome_message'] ); ?>"></td>
							</tr>
							<tr>
								<th scope="row"><label for="orsc-placeholder"><?php esc_html_e( 'Input placeholder', 'jayanta-ai-site-chatbot-with-openrouter' ); ?></label></th>
								<td><input id="orsc-placeholder" type="text" class="regular-text" name="<?php echo esc_attr( ORSC_OPTION ); ?>[placeholder]" value="<?php echo esc_attr( $settings['placeholder'] ); ?>"></td>
							</tr>
							<tr>
								<th scope="row"><label for="orsc-primary-color"><?php esc_html_e( 'Primary color', 'jayanta-ai-site-chatbot-with-openrouter' ); ?></label></th>
								<td><input id="orsc-primary-color" type="color" name="<?php echo esc_attr( ORSC_OPTION ); ?>[primary_color]" value="<?php echo esc_attr( $settings['primary_color'] ); ?>"></td>
							</tr>
							<tr>
								<th scope="row"><?php esc_html_e( 'Content types', 'jayanta-ai-site-chatbot-with-openrouter' ); ?></th>
								<td>
									<?php foreach ( $post_types as $type ) : ?>
										<label class="orsc-admin__check"><input type="checkbox" name="<?php echo esc_attr( ORSC_OPTION ); ?>[post_types][]" value="<?php echo esc_attr( $type->name ); ?>" <?php checked( in_array( $type->name, $settings['post_types'], true ) ); ?>> <?php echo esc_html( $type->labels->name ); ?></label>
									<?php endforeach; ?>
								</td>
							</tr>
							<tr>
								<th scope="row"><label for="orsc-index-limit"><?php esc_html_e( 'Index limit', 'jayanta-ai-site-chatbot-with-openrouter' ); ?></label></th>
								<td><input id="orsc-index-limit" type="number" min="10" max="1000" name="<?php echo esc_attr( ORSC_OPTION ); ?>[index_limit]" value="<?php echo esc_attr( $settings['index_limit'] ); ?>"> <span class="description"><?php esc_html_e( 'Most recently modified public items.', 'jayanta-ai-site-chatbot-with-openrouter' ); ?></span></td>
							</tr>
							<tr>
								<th scope="row"><label for="orsc-max-sources"><?php esc_html_e( 'Sources per answer', 'jayanta-ai-site-chatbot-with-openrouter' ); ?></label></th>
								<td><input id="orsc-max-sources" type="number" min="1" max="10" name="<?php echo esc_attr( ORSC_OPTION ); ?>[max_sources]" value="<?php echo esc_attr( $settings['max_sources'] ); ?>"></td>
							</tr>
							<tr>
								<th scope="row"><label for="orsc-context"><?php esc_html_e( 'Context characters', 'jayanta-ai-site-chatbot-with-openrouter' ); ?></label></th>
								<td><input id="orsc-context" type="number" min="1000" max="16000" name="<?php echo esc_attr( ORSC_OPTION ); ?>[context_characters]" value="<?php echo esc_attr( $settings['context_characters'] ); ?>"></td>
							</tr>
							<tr>
								<th scope="row"><label for="orsc-max-tokens"><?php esc_html_e( 'Max answer tokens', 'jayanta-ai-site-chatbot-with-openrouter' ); ?></label></th>
								<td><input id="orsc-max-tokens" type="number" min="150" max="2000" name="<?php echo esc_attr( ORSC_OPTION ); ?>[max_tokens]" value="<?php echo esc_attr( $settings['max_tokens'] ); ?>"></td>
							</tr>
							<tr>
								<th scope="row"><label for="orsc-temp"><?php esc_html_e( 'Temperature', 'jayanta-ai-site-chatbot-with-openrouter' ); ?></label></th>
								<td><input id="orsc-temp" type="number" min="0" max="1" step="0.1" name="<?php echo esc_attr( ORSC_OPTION ); ?>[temperature]" value="<?php echo esc_attr( $settings['temperature'] ); ?>"></td>
							</tr>
							<tr>
								<th scope="row"><label for="orsc-rate"><?php esc_html_e( 'Hourly visitor limit', 'jayanta-ai-site-chatbot-with-openrouter' ); ?></label></th>
								<td><input id="orsc-rate" type="number" min="1" max="200" name="<?php echo esc_attr( ORSC_OPTION ); ?>[rate_limit]" value="<?php echo esc_attr( $settings['rate_limit'] ); ?>"></td>
							</tr>
							<tr>
								<th scope="row"><?php esc_html_e( 'Chat logs', 'jayanta-ai-site-chatbot-with-openrouter' ); ?></th>
								<td><label><input type="checkbox" name="<?php echo esc_attr( ORSC_OPTION ); ?>[log_chats]" value="1" <?php checked( $settings['log_chats'], 1 ); ?>> <?php esc_html_e( 'Keep the last 30 compact chat records without storing full answers.', 'jayanta-ai-site-chatbot-with-openrouter' ); ?></label></td>
							</tr>
						</table>
						<?php submit_button(); ?>
					</form>
				</section>

				<aside class="orsc-admin__panel">
					<h2><?php esc_html_e( 'Content Index', 'jayanta-ai-site-chatbot-with-openrouter' ); ?></h2>
					<p><strong><?php esc_html_e( 'Indexed items:', 'jayanta-ai-site-chatbot-with-openrouter' ); ?></strong> <span id="orsc-index-count"><?php echo esc_html( isset( $index['doc_count'] ) ? absint( $index['doc_count'] ) : 0 ); ?></span></p>
					<p><strong><?php esc_html_e( 'Last built:', 'jayanta-ai-site-chatbot-with-openrouter' ); ?></strong> <span id="orsc-index-built"><?php echo esc_html( isset( $index['built_at'] ) ? $index['built_at'] : __( 'Not built yet', 'jayanta-ai-site-chatbot-with-openrouter' ) ); ?></span></p>
					<button type="button" class="button button-primary" id="orsc-rebuild-index"><?php esc_html_e( 'Rebuild Index', 'jayanta-ai-site-chatbot-with-openrouter' ); ?></button>
					<p id="orsc-rebuild-status" class="description"></p>
					<hr>
					<h3><?php esc_html_e( 'Security Notes', 'jayanta-ai-site-chatbot-with-openrouter' ); ?></h3>
					<ul class="orsc-admin__list">
						<li><?php esc_html_e( 'Only published public content is indexed.', 'jayanta-ai-site-chatbot-with-openrouter' ); ?></li>
						<li><?php esc_html_e( 'OpenRouter requests run on the server.', 'jayanta-ai-site-chatbot-with-openrouter' ); ?></li>
						<li><?php esc_html_e( 'Visitor requests use WordPress nonces and hourly rate limits.', 'jayanta-ai-site-chatbot-with-openrouter' ); ?></li>
						<li><?php esc_html_e( 'Session chat history is stored in the visitor browser session.', 'jayanta-ai-site-chatbot-with-openrouter' ); ?></li>
					</ul>
				</aside>
			</div>

			<section class="orsc-admin__panel orsc-admin__logs">
				<h2><?php esc_html_e( 'Recent Chats', 'jayanta-ai-site-chatbot-with-openrouter' ); ?></h2>
				<?php if ( empty( $logs ) || ! is_array( $logs ) ) : ?>
					<p><?php esc_html_e( 'No chats logged yet.', 'jayanta-ai-site-chatbot-with-openrouter' ); ?></p>
				<?php else : ?>
					<table class="widefat striped">
						<thead><tr><th><?php esc_html_e( 'Time', 'jayanta-ai-site-chatbot-with-openrouter' ); ?></th><th><?php esc_html_e( 'Question', 'jayanta-ai-site-chatbot-with-openrouter' ); ?></th><th><?php esc_html_e( 'Sources', 'jayanta-ai-site-chatbot-with-openrouter' ); ?></th><th><?php esc_html_e( 'Tokens', 'jayanta-ai-site-chatbot-with-openrouter' ); ?></th></tr></thead>
						<tbody>
						<?php foreach ( array_reverse( $logs ) as $log ) : ?>
							<tr>
								<td><?php echo esc_html( isset( $log['time'] ) ? $log['time'] : '' ); ?></td>
								<td><?php echo esc_html( isset( $log['question'] ) ? $log['question'] : '' ); ?></td>
								<td><?php echo esc_html( isset( $log['source_count'] ) ? absint( $log['source_count'] ) : 0 ); ?></td>
								<td><?php echo esc_html( isset( $log['tokens'] ) ? absint( $log['tokens'] ) : 0 ); ?></td>
							</tr>
						<?php endforeach; ?>
						</tbody>
					</table>
				<?php endif; ?>
			</section>
		</div>
		<?php
	}
}
