<?php
/**
 * Frontend conversation history admin page.
 *
 * @package Niwa_AI
 */

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

class Niwa_AI_Conversation_History_Page {

	/** Register the History submenu. */
	public function register_hooks() {
		add_action( 'admin_menu', array( $this, 'add_submenu' ), 20 );
		add_action( 'wp_ajax_niwa_ai_history_transcript', array( $this, 'ajax_transcript' ) );
	}

	/** Return one transcript panel without reloading the session list. */
	public function ajax_transcript() {
		if ( ! current_user_can( 'manage_options' ) ) {
			wp_send_json_error( array( 'message' => __( 'Forbidden', 'niwa-ai' ) ), 403 );
		}

		check_ajax_referer( 'niwa_ai_history_transcript', 'nonce' );
		$session_id = isset( $_POST['session'] ) ? sanitize_text_field( wp_unslash( $_POST['session'] ) ) : '';
		if ( '' === $session_id ) {
			wp_send_json_error( array( 'message' => __( 'Session is required.', 'niwa-ai' ) ), 400 );
		}

		ob_start();
		$this->render_transcript( new Niwa_AI_Frontend_Question_Log(), $session_id );
		$html = ob_get_clean();

		wp_send_json_success(
			array(
				'html'    => $html,
				'session' => $session_id,
			)
		);
	}

	/** Add the History entry below Lead Capture. */
	public function add_submenu() {
		add_submenu_page(
			'niwa-ai',
			__( 'Conversation History', 'niwa-ai' ),
			__( 'History', 'niwa-ai' ),
			'manage_options',
			'niwa-ai-history',
			array( $this, 'render_page' )
		);
	}

	/** Render the paginated session list and selected transcript. */
	public function render_page() {
		if ( ! current_user_can( 'manage_options' ) ) {
			wp_die( 'Forbidden' );
		}

		$search     = isset( $_GET['s'] ) ? sanitize_text_field( wp_unslash( $_GET['s'] ) ) : '';
		$paged      = isset( $_GET['paged'] ) ? max( 1, absint( $_GET['paged'] ) ) : 1;
		$session_id = isset( $_GET['session'] ) ? sanitize_text_field( wp_unslash( $_GET['session'] ) ) : '';
		$per_page   = 20;
		$log        = new Niwa_AI_Frontend_Question_Log();
		$result     = $log->get_sessions( $search, $per_page, ( $paged - 1 ) * $per_page );
		$items      = isset( $result['items'] ) && is_array( $result['items'] ) ? $result['items'] : array();
		if ( '' === $session_id && ! empty( $items[0]['session_id'] ) ) {
			$session_id = (string) $items[0]['session_id'];
		}
		$selected = array();
		foreach ( $items as $item ) {
			if ( $session_id === (string) ( $item['session_id'] ?? '' ) ) {
				$selected = $item;
				break;
			}
		}

		echo '<div class="wrap niwa-wrap niwa-history">';
		$this->render_header();
		echo '<div class="niwa-history-layout">';
		$this->render_sessions( $result, $search, $paged, $per_page, $session_id );
		$this->render_transcript( $log, $session_id, $selected );
		echo '</div>';
		echo '</div>';
	}

	/** Render page heading. */
	private function render_header() {
		echo '<div class="niwa-page-header">';
		echo '<div class="niwa-page-header__icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15a4 4 0 0 1-4 4H8l-5 3V7a4 4 0 0 1 4-4h10a4 4 0 0 1 4 4z"/><path d="M8 9h8"/><path d="M8 13h5"/></svg></div>';
		echo '<div class="niwa-page-header__text"><h1 class="niwa-page-header__title">' . esc_html__( 'Conversation History', 'niwa-ai' ) . '</h1>';
		echo '<p class="niwa-page-header__subtitle">' . esc_html__( 'Browse frontend chat sessions and read every recorded customer exchange.', 'niwa-ai' ) . '</p></div>';
		echo '</div>';
	}

	/**
	 * Render one complete session transcript.
	 *
	 * @param Niwa_AI_Frontend_Question_Log $log        Persistent conversation log.
	 * @param string                        $session_id Session identifier.
	 * @param array                         $summary    Session list summary.
	 */
	private function render_transcript( $log, $session_id, $summary = array() ) {
		echo '<section class="niwa-history-chat-pane" data-session="' . esc_attr( $session_id ) . '" aria-label="' . esc_attr__( 'Conversation', 'niwa-ai' ) . '" aria-live="polite" tabindex="-1">';
		if ( '' === $session_id ) {
			echo '<div class="niwa-history-chat-empty"><span class="niwa-history-chat-empty__icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7"><path d="M21 15a4 4 0 0 1-4 4H8l-5 3V7a4 4 0 0 1 4-4h10a4 4 0 0 1 4 4z"/><path d="M8 9h8M8 13h5"/></svg></span><h2>' . esc_html__( 'Choose a session', 'niwa-ai' ) . '</h2><p>' . esc_html__( 'Select a conversation on the left to read the complete exchange.', 'niwa-ai' ) . '</p></div>';
			echo '</section>';
			return;
		}

		$turns         = $log->get_session_transcript( $session_id );
		$turn_count    = isset( $summary['turn_count'] ) ? absint( $summary['turn_count'] ) : count( $turns );
		$last_activity = (string) ( $summary['last_activity'] ?? ( ! empty( $turns ) ? ( $turns[ count( $turns ) - 1 ]['created_at'] ?? '' ) : '' ) );
		$label         = $this->get_session_label( $session_id );
		$turn_label    = sprintf(
			/* translators: %s: turn count. */
			_n( '%s turn', '%s turns', $turn_count, 'niwa-ai' ),
			(string) $turn_count
		);

		echo '<header class="niwa-history-chat-header">';
		echo '<span class="niwa-history-chat-avatar" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><path d="M20 21a8 8 0 0 0-16 0"/><circle cx="12" cy="7" r="4"/></svg></span>';
		echo '<div class="niwa-history-chat-heading"><h2>' . esc_html( $label ) . '</h2><p>' . esc_html(
			sprintf(
				/* translators: 1: localized turn count, 2: last activity datetime. */
				__( '%1$s · Last activity %2$s', 'niwa-ai' ),
				$turn_label,
				$this->format_datetime( $last_activity )
			)
		) . '</p></div>';
		echo '<details class="niwa-history-session-details"><summary>' . esc_html__( 'Session ID', 'niwa-ai' ) . '</summary><code>' . esc_html( $session_id ) . '</code></details>';
		echo '</header>';
		echo '<div class="niwa-history-chat-scroll"><div class="niwa-history-transcript">';

		if ( empty( $turns ) ) {
			echo '<div class="niwa-history-chat-empty"><h2>' . esc_html__( 'No recorded messages', 'niwa-ai' ) . '</h2><p>' . esc_html__( 'This session exists, but its transcript is empty.', 'niwa-ai' ) . '</p></div>';
		}

		$first_created = ! empty( $turns[0]['created_at'] ) ? $this->format_datetime( $turns[0]['created_at'] ) : '';
		if ( '' !== $first_created ) {
			echo '<div class="niwa-history-date-divider"><span>' . esc_html( $first_created ) . '</span></div>';
		}
		foreach ( $turns as $turn ) {
			$created = $this->format_datetime( $turn['created_at'] ?? '' );
			$this->render_message( 'customer', __( 'Customer', 'niwa-ai' ), (string) ( $turn['question'] ?? '' ), $created );
			$this->render_message( 'assistant', __( 'Niwa', 'niwa-ai' ), (string) ( $turn['answer_summary'] ?? '' ), $created );
		}

		echo '<span id="niwa-history-chat-end" aria-hidden="true"></span></div></div></section>';
	}

	/** Render one transcript message. */
	private function render_message( $role, $label, $text, $created ) {
		$text = trim( (string) $text );
		if ( '' === $text ) {
			return;
		}

		echo '<article class="niwa-history-message niwa-history-message--' . esc_attr( $role ) . '">';
		echo '<div class="niwa-history-message__meta"><strong>' . esc_html( $label ) . '</strong><time>' . esc_html( $created ) . '</time></div>';
		echo '<div class="niwa-history-message__text">' . nl2br( esc_html( $text ) ) . '</div>';
		echo '</article>';
	}

	/** Render the searchable session rail. */
	private function render_sessions( $result, $search, $paged, $per_page, $selected_session_id = '' ) {
		$items = isset( $result['items'] ) && is_array( $result['items'] ) ? $result['items'] : array();
		$total = isset( $result['total'] ) ? absint( $result['total'] ) : 0;
		$pages = max( 1, (int) ceil( $total / $per_page ) );

		echo '<aside class="niwa-history-sidebar"><div class="niwa-history-sidebar-header">';
		echo '<div class="niwa-history-sidebar-title"><h2>' . esc_html__( 'Sessions', 'niwa-ai' ) . '</h2><span>' . esc_html( (string) $total ) . '</span></div>';
		echo '<form method="get" class="niwa-history-search"><input type="hidden" name="page" value="niwa-ai-history" /><label class="screen-reader-text" for="niwa-history-search">' . esc_html__( 'Search sessions or messages', 'niwa-ai' ) . '</label>';
		echo '<span class="niwa-history-search-icon" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="11" cy="11" r="7"/><path d="m20 20-4-4"/></svg></span>';
		echo '<input id="niwa-history-search" type="search" name="s" value="' . esc_attr( $search ) . '" placeholder="' . esc_attr__( 'Search conversations', 'niwa-ai' ) . '" />';
		echo '<button type="submit" aria-label="' . esc_attr__( 'Search', 'niwa-ai' ) . '"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="m9 18 6-6-6-6"/></svg></button>';
		echo '</form>';
		if ( '' !== $search ) {
			$clear_url = add_query_arg( array( 'page' => 'niwa-ai-history' ), admin_url( 'admin.php' ) );
			echo '<a class="niwa-history-search-clear" href="' . esc_url( $clear_url ) . '">' . esc_html__( 'Clear', 'niwa-ai' ) . '</a>';
		}
		echo '</div><nav class="niwa-history-session-list" aria-label="' . esc_attr__( 'Conversation sessions', 'niwa-ai' ) . '">';

		if ( empty( $items ) ) {
			echo '<div class="niwa-history-sidebar-empty"><strong>' . esc_html__( 'No sessions found', 'niwa-ai' ) . '</strong><span>' . esc_html__( 'Try a different search.', 'niwa-ai' ) . '</span></div>';
		}

		foreach ( $items as $item ) {
			$session_id = (string) ( $item['session_id'] ?? '' );
			$is_active   = $session_id === (string) $selected_session_id;
			$view_url   = add_query_arg(
				array_filter(
					array(
						'page'    => 'niwa-ai-history',
						'session' => $session_id,
						'paged'   => $paged > 1 ? $paged : null,
						's'       => '' !== $search ? $search : null,
					),
					static function ( $value ) { return null !== $value; }
				),
				admin_url( 'admin.php' )
			);
			$question = trim( (string) ( $item['question_preview'] ?? '' ) );
			$answer   = trim( (string) ( $item['answer_preview'] ?? $item['preview'] ?? '' ) );
			echo '<a class="niwa-history-session-item' . ( $is_active ? ' is-active' : '' ) . '" href="' . esc_url( $view_url ) . '" data-session="' . esc_attr( $session_id ) . '"' . ( $is_active ? ' aria-current="page"' : '' ) . '>';
			echo '<span class="niwa-history-session-avatar" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><path d="M20 21a8 8 0 0 0-16 0"/><circle cx="12" cy="7" r="4"/></svg></span>';
			echo '<span class="niwa-history-session-copy"><span class="niwa-history-session-top"><strong>' . esc_html( $this->get_session_label( $session_id ) ) . '</strong><time>' . esc_html( $this->format_list_datetime( $item['last_activity'] ?? '' ) ) . '</time></span>';
			echo '<span class="niwa-history-session-question">' . esc_html( wp_html_excerpt( '' !== $question ? $question : __( 'Conversation', 'niwa-ai' ), 58, '…' ) ) . '</span>';
			if ( '' !== $answer ) {
				echo '<span class="niwa-history-session-answer"><b>' . esc_html__( 'Niwa:', 'niwa-ai' ) . '</b> ' . esc_html( wp_html_excerpt( $answer, 82, '…' ) ) . '</span>';
			}
			echo '<span class="niwa-history-session-meta">' . esc_html(
				sprintf(
					/* translators: %s: turn count. */
					_n( '%s turn', '%s turns', absint( $item['turn_count'] ?? 0 ), 'niwa-ai' ),
					(string) absint( $item['turn_count'] ?? 0 )
				)
			) . '</span></span></a>';
		}

		echo '</nav>';
		$this->render_pagination( $paged, $pages, $search );
		echo '</aside>';
	}

	/** Render compact pagination controls. */
	private function render_pagination( $paged, $pages, $search ) {
		if ( $pages <= 1 ) {
			return;
		}

		$build_url = static function ( $page ) use ( $search ) {
			return add_query_arg(
				array_filter(
					array( 'page' => 'niwa-ai-history', 'paged' => $page, 's' => '' !== $search ? $search : null ),
					static function ( $value ) { return null !== $value; }
				),
				admin_url( 'admin.php' )
			);
		};

		echo '<div class="niwa-history-pagination">';
		if ( $paged > 1 ) {
			echo '<a href="' . esc_url( $build_url( $paged - 1 ) ) . '" aria-label="' . esc_attr__( 'Previous page', 'niwa-ai' ) . '">&larr;</a>';
		} else {
			echo '<span aria-hidden="true">&larr;</span>';
		}
		echo '<small>' . esc_html( sprintf( __( '%1$s / %2$s', 'niwa-ai' ), (string) $paged, (string) $pages ) ) . '</small>';
		if ( $paged < $pages ) {
			echo '<a href="' . esc_url( $build_url( $paged + 1 ) ) . '" aria-label="' . esc_attr__( 'Next page', 'niwa-ai' ) . '">&rarr;</a>';
		} else {
			echo '<span aria-hidden="true">&rarr;</span>';
		}
		echo '</div>';
	}

	/** Return a short privacy-safe label for an anonymous frontend session. */
	private function get_session_label( $session_id ) {
		return sprintf(
			/* translators: %s: short anonymous session code. */
			__( 'Visitor %s', 'niwa-ai' ),
			strtoupper( substr( hash( 'sha256', (string) $session_id ), 0, 6 ) )
		);
	}

	/** Format compact timestamps for the session rail. */
	private function format_list_datetime( $value ) {
		$value = trim( (string) $value );
		if ( '' === $value ) {
			return '';
		}

		$timestamp = strtotime( $value . ' UTC' );
		return false === $timestamp ? $value : wp_date( 'M j, H:i', $timestamp );
	}

	/** Convert stored UTC datetimes to the configured WordPress timezone. */
	private function format_datetime( $value ) {
		$value = trim( (string) $value );
		if ( '' === $value ) {
			return '—';
		}

		$timestamp = strtotime( $value . ' UTC' );
		return false === $timestamp
			? $value
			: wp_date( get_option( 'date_format' ) . ' ' . get_option( 'time_format' ), $timestamp );
	}
}
