<?php
/**
 * NeccoSpeak — Agent UI: 変更履歴 タブ（本番 ai-agent-embed v1.5.1.1 の
 * 「変更履歴」タブと同じ見た目・同じ画面構成で描画する）。
 *
 * 本番の変更履歴タブ（includes/admin-agent-settings.php
 * ai_agent_embed_render_tab_logs()）はバックエンドの監査ログAPIを
 * 日時/操作者/対象/操作(バッジ)/詳細（トグル）の5列テーブル＋
 * 表示件数セレクタ／前後ページングで一覧表示する（本番JS:
 * assets/js/admin-agent-settings.js renderLogs()/updateLogsPaginationControls()、
 * 本番CSS: assets/css/admin-agent-settings.css .ai-agent-log-action--* /
 * .ai-agent-log-detail — 確認済みクラス名はいずれも
 * assets/agent-ui/css/admin-agent-settings.css に既に本番と同一の定義で
 * コピーされている）。
 *
 * NeccoSpeak には本番同型のバックエンド監査APIは無いが、同じ役割のデータを
 * includes/admin-versions.php / includes/db.php のバージョン履歴
 * (wp_neccospeak_versions、neccospeak_db_get_versions()) が既に持っている
 * ── created_at/user_login/origin(save|publish|rollback|discard)/changed_keys
 * ── ので、それを本番と同じ列構成にマッピングして描画する。行内の個別
 * 「ロールバック」ボタンは本番同様に置かず（dashboardタブの
 * neccospeak_agent_ui_dashboard_render_rollback_form() に集約済み）。
 *
 * @package NeccoSpeak
 */

defined( 'ABSPATH' ) || exit;

/**
 * 変更履歴 タブ本体。
 *
 * @param array $opts neccospeak_editing_options() 相当（このタブでは未使用だが
 *                     契約のシグネチャに合わせて受け取る）。
 * @return void
 */
function neccospeak_agent_ui_tab_history( $opts ) {
	unset( $opts ); // このタブは includes/db.php のバージョン履歴を直接読む。
	?>
	<div class="ai-agent-section" id="ai-agent-logs">
		<h2><?php esc_html_e( 'Change history (audit log)', 'neccospeak' ); ?></h2>
		<p class="description"><?php esc_html_e( 'Change history of the agent settings.', 'neccospeak' ); ?></p>

		<?php neccospeak_agent_ui_history_render_table(); ?>
	</div>
	<?php
}

/**
 * 本番の「表示件数」セレクタと同じ選択肢。
 *
 * @return int[]
 */
function neccospeak_agent_ui_history_page_sizes() {
	return array( 50, 100, 200 );
}

/**
 * 本番 origin/action 語彙（save|publish|rollback|discard）→
 * 本番CSSの .ai-agent-log-action--{publish|update|create|delete|rollback}
 * のどれに対応させるかのマッピング。NeccoSpeakの「discard(下書き破棄)」は
 * 本番語彙に対応が無いため、見た目が近い delete(赤系)を割り当てる。
 *
 * @return array<string,string> origin => バッジclass修飾子。
 */
function neccospeak_agent_ui_history_action_classes() {
	return array(
		'save'     => 'update',
		'publish'  => 'publish',
		'rollback' => 'rollback',
		'discard'  => 'delete',
	);
}

/**
 * 本番と同じ英語表記のバッジ文言（save→update、他はそのまま）。
 *
 * @return array<string,string> origin => バッジ表示文言。
 */
function neccospeak_agent_ui_history_action_labels() {
	return array(
		'save'     => __( 'update', 'neccospeak' ),
		'publish'  => __( 'publish', 'neccospeak' ),
		'rollback' => __( 'rollback', 'neccospeak' ),
		'discard'  => __( 'discard', 'neccospeak' ),
	);
}

/**
 * created_at (UTC, MySQL DATETIME文字列) をサイトのタイムゾーン/フォーマットで
 * 表示用に変換する。includes/admin-versions.php neccospeak_render_versions_view()
 * と同じロジック。
 *
 * @param string $created_at
 * @return string
 */
function neccospeak_agent_ui_history_format_date( $created_at ) {
	if ( '' === $created_at || ! function_exists( 'wp_date' ) ) {
		return $created_at;
	}
	$ts = strtotime( $created_at . ' UTC' );
	if ( ! $ts ) {
		return $created_at;
	}
	$format = trim( get_option( 'date_format', 'Y-m-d' ) . ' ' . get_option( 'time_format', 'H:i' ) );
	return wp_date( '' !== $format ? $format : 'Y-m-d H:i', $ts );
}

/**
 * テーブル＋ページングコントロールを描画する。
 *
 * @return void
 */
function neccospeak_agent_ui_history_render_table() {
	if ( ! function_exists( 'neccospeak_db_ready' ) || ! neccospeak_db_ready() ) {
		echo '<p class="description">' . esc_html__( 'Could not load the change history feature.', 'neccospeak' ) . '</p>';
		return;
	}

	$sizes     = neccospeak_agent_ui_history_page_sizes();
	$page_size = isset( $_GET['hist_size'] ) ? (int) $_GET['hist_size'] : 50; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- 読み取り専用のページングUI（状態変更なし）。
	if ( ! in_array( $page_size, $sizes, true ) ) {
		$page_size = 50;
	}
	$page = isset( $_GET['hist_page'] ) ? max( 1, (int) $_GET['hist_page'] ) : 1; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- 読み取り専用のページングUI（状態変更なし）。

	// neccospeak_db_paging() は per_page を NECCOSPEAK_MAX_PAGE_SIZE（既定100）で
	// 上限クランプする。本番同様に選択肢へ「200」を残しつつ、以降のクエリ・
	// ページング計算は実際にDB層が使う値と必ず一致させる（不一致だと
	// 「次へ」が誤って無効化されたり、表示件数の起点がずれるバグになる）。
	if ( defined( 'NECCOSPEAK_MAX_PAGE_SIZE' ) && $page_size > (int) NECCOSPEAK_MAX_PAGE_SIZE ) {
		$page_size = (int) NECCOSPEAK_MAX_PAGE_SIZE;
	}

	$rows  = array();
	$total = 0;
	if ( function_exists( 'neccospeak_db_get_versions' ) ) {
		$result = neccospeak_db_get_versions(
			array(
				'page'     => $page,
				'per_page' => $page_size,
			)
		);
		$rows  = ( isset( $result['rows'] ) && is_array( $result['rows'] ) ) ? array_values( $result['rows'] ) : array();
		$total = isset( $result['total'] ) ? (int) $result['total'] : 0;
	}

	$base_args = array(
		'page' => defined( 'NECCOSPEAK_SETTINGS_SLUG' ) ? NECCOSPEAK_SETTINGS_SLUG : 'neccospeak',
		'tab'  => 'history',
	);

	/* ── 本番同様の「表示件数」＋「前の◯件／次の◯件」コントロール（Issue #117 Phase 1 相当） ── */
	echo '<div class="ai-agent-logs-controls" style="display:flex; gap:8px; align-items:center; flex-wrap:wrap; margin-bottom:8px;">';

	echo '<form method="get" action="' . esc_url( admin_url( 'admin.php' ) ) . '" style="display:flex; gap:4px; align-items:center;">';
	foreach ( $base_args as $key => $value ) {
		echo '<input type="hidden" name="' . esc_attr( $key ) . '" value="' . esc_attr( $value ) . '" />';
	}
	echo '<input type="hidden" name="hist_page" value="1" />';
	echo '<label style="display:flex; align-items:center; gap:4px;">';
	echo '<span style="font-size:12px; color:#666;">' . esc_html__( 'Rows per page:', 'neccospeak' ) . '</span>';
	echo '<select name="hist_size" class="ai-agent-logs-page-size" onchange="this.form.submit()">';
	foreach ( $sizes as $size ) {
		echo '<option value="' . esc_attr( (string) $size ) . '" ' . selected( $page_size, $size, false ) . '>' . esc_html( (string) $size ) . '</option>';
	}
	echo '</select>';
	echo '</label>';
	echo '<noscript><button type="submit" class="button button-small">' . esc_html__( 'Show', 'neccospeak' ) . '</button></noscript>';
	echo '</form>';

	$has_prev = $page > 1;
	$has_next = ( $page * $page_size ) < $total;

	if ( $has_prev ) {
		$prev_url = add_query_arg(
			array_merge( $base_args, array( 'hist_size' => $page_size, 'hist_page' => $page - 1 ) ),
			admin_url( 'admin.php' )
		);
		echo '<a class="button button-small" href="' . esc_url( $prev_url ) . '">' . esc_html(
			sprintf(
				/* translators: %d: page size (number of rows fetched per page). */
				__( 'Previous %d entries', 'neccospeak' ),
				$page_size
			)
		) . '</a>';
	} else {
		echo '<button type="button" class="button button-small" disabled>' . esc_html(
			sprintf(
				/* translators: %d: page size (number of rows fetched per page). */
				__( 'Previous %d entries', 'neccospeak' ),
				$page_size
			)
		) . '</button>';
	}

	if ( $has_next ) {
		$next_url = add_query_arg(
			array_merge( $base_args, array( 'hist_size' => $page_size, 'hist_page' => $page + 1 ) ),
			admin_url( 'admin.php' )
		);
		echo '<a class="button button-small" href="' . esc_url( $next_url ) . '">' . esc_html(
			sprintf(
				/* translators: %d: page size (number of rows fetched per page). */
				__( 'Next %d entries', 'neccospeak' ),
				$page_size
			)
		) . '</a>';
	} else {
		echo '<button type="button" class="button button-small" disabled>' . esc_html(
			sprintf(
				/* translators: %d: page size (number of rows fetched per page). */
				__( 'Next %d entries', 'neccospeak' ),
				$page_size
			)
		) . '</button>';
	}

	if ( $total > 0 && ! empty( $rows ) ) {
		$from = ( ( $page - 1 ) * $page_size ) + 1;
		$to   = $from + count( $rows ) - 1;
		echo '<span class="description" style="font-size:12px; color:#666;">' . esc_html(
			sprintf(
				/* translators: 1: first row number shown, 2: last row number shown, 3: total row count. */
				__( 'Showing entries %1$d–%2$d (of %3$d total)', 'neccospeak' ),
				$from,
				$to,
				$total
			)
		) . '</span>';
	}
	echo '</div>';

	if ( empty( $rows ) ) {
		echo '<p>' . esc_html__( 'No change history yet.', 'neccospeak' ) . '</p>';
		return;
	}

	$action_classes = neccospeak_agent_ui_history_action_classes();
	$action_labels  = neccospeak_agent_ui_history_action_labels();

	echo '<table id="ai-agent-logs-table" class="wp-list-table widefat fixed striped">';
	echo '<thead><tr>';
	echo '<th style="width:160px;">' . esc_html__( 'Date/time', 'neccospeak' ) . '</th>';
	echo '<th style="width:140px;">' . esc_html__( 'Performed by', 'neccospeak' ) . '</th>';
	echo '<th style="width:180px;">' . esc_html__( 'Target', 'neccospeak' ) . '</th>';
	echo '<th style="width:80px;">' . esc_html__( 'Action', 'neccospeak' ) . '</th>';
	echo '<th>' . esc_html__( 'Details', 'neccospeak' ) . '</th>';
	echo '</tr></thead><tbody>';

	foreach ( $rows as $raw_row ) {
		$row     = (array) $raw_row;
		$created = isset( $row['created_at'] ) ? (string) $row['created_at'] : '';
		$when    = neccospeak_agent_ui_history_format_date( $created );

		$actor  = ( isset( $row['user_login'] ) && '' !== $row['user_login'] ) ? (string) $row['user_login'] : __( '(unknown)', 'neccospeak' );
		$origin = isset( $row['origin'] ) ? (string) $row['origin'] : 'save';

		$changed_keys = array();
		if ( isset( $row['changed_keys'] ) && is_string( $row['changed_keys'] ) && '' !== $row['changed_keys'] ) {
			$decoded = json_decode( $row['changed_keys'], true );
			if ( is_array( $decoded ) ) {
				$changed_keys = $decoded;
			}
		}

		// 対象＝変更キーの要約（先頭2件＋残数）。
		$shown_keys = array_slice( $changed_keys, 0, 2 );
		$target     = implode( ', ', $shown_keys );
		$remaining  = count( $changed_keys ) - count( $shown_keys );
		if ( $remaining > 0 ) {
			$target .= sprintf(
				/* translators: %d: number of additional changed setting keys not individually listed. */
				__( ' and %d more', 'neccospeak' ),
				$remaining
			);
		}
		if ( '' === $target ) {
			$target = '—';
		}

		$action_class = isset( $action_classes[ $origin ] ) ? $action_classes[ $origin ] : 'update';
		$action_label = isset( $action_labels[ $origin ] ) ? $action_labels[ $origin ] : $origin;

		echo '<tr>';
		echo '<td>' . esc_html( $when ) . '</td>';
		echo '<td>' . esc_html( $actor ) . '</td>';
		echo '<td>' . esc_html( $target ) . '</td>';
		echo '<td><span class="ai-agent-log-action ai-agent-log-action--' . esc_attr( $action_class ) . '">' . esc_html( $action_label ) . '</span></td>';
		echo '<td>';
		if ( ! empty( $changed_keys ) ) {
			echo '<details class="ai-agent-log-detail"><summary>' . esc_html__( 'Show details', 'neccospeak' ) . '</summary>';
			echo '<pre>' . esc_html( implode( "\n", $changed_keys ) ) . '</pre>';
			echo '</details>';
		} else {
			echo '<span class="description">—</span>';
		}
		echo '</td>';
		echo '</tr>';
	}

	echo '</tbody></table>';
}
