<?php
/**
 * Activity_Page — renders the Activity tab inside the Ppok AI Toolkit settings
 * page. Wraps Activity_List_Table with filter controls and a row-detail screen
 * that pretty-prints payload + renders a diff view when payload.diff is
 * populated (Phase 6+ narrow writes; current rest-call rows show an empty
 * state).
 *
 * @package Ppok\AIToolkit
 * @license GPL-2.0-or-later
 */

namespace Ppok\AIToolkit\Admin;

use Ppok\AIToolkit\Event_Logger;

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

final class Activity_Page {

	public const CAP = 'manage_options';

	private string $base_url = '';

	/**
	 * Render the activity tab inside the Settings page wrap.
	 *
	 * @param string $base_url Settings page URL the tab links back to (without
	 *                         filter query args). Used to build self-links so
	 *                         the row-detail screen + reset button stay on the
	 *                         settings page.
	 */
	public function render( string $base_url ): void {
		if ( ! current_user_can( self::CAP ) ) {
			return;
		}

		$this->base_url = $base_url;

		$action = isset( $_GET['action'] ) ? sanitize_key( (string) wp_unslash( $_GET['action'] ) ) : '';
		if ( 'view' === $action && isset( $_GET['id'] ) ) {
			$this->render_detail( (int) $_GET['id'] );
			return;
		}

		$this->render_list();
	}

	private function render_list(): void {
		$table = new Activity_List_Table( $this->base_url );
		$table->prepare_items();

		echo '<p>' . esc_html__( 'Every MCP-attributed write through a Ppok ability lands here. Reads are not logged in v1.', 'ppok-ai-toolkit' ) . '</p>';

		$this->render_filters();

		// Search is part of the unified filter form above; no need for the
		// list-table's separate search box. The table just renders rows.
		$table->display();
	}

	private function render_filters(): void {
		$result_options = array(
			'ok',
			'permission_denied',
			'validation_error',
			'not_found',
			'unknown_block',
			'scope_blocked',
			'server_error',
		);

		$ability_options = $this->distinct_column_values( 'ability_slug' );
		$client_options  = $this->distinct_column_values( 'mcp_client' );
		$error_options   = $this->distinct_column_values( 'error_code' );

		$search = isset( $_GET['s'] ) ? sanitize_text_field( (string) wp_unslash( $_GET['s'] ) ) : '';

		echo '<form method="get" class="ppok-activity-filters" style="margin:1em 0;padding:1em;background:#fff;border:1px solid #c3c4c7">';
		$this->preserve_query_args( array( 'page', 'tab' ) );

		echo '<div style="display:grid;grid-template-columns:repeat(auto-fit, minmax(180px, 1fr));gap:.75em 1em;align-items:end">';

		$this->select_field( 'ability_slug', __( 'Ability', 'ppok-ai-toolkit' ), $ability_options );
		$this->select_field( 'result', __( 'Result', 'ppok-ai-toolkit' ), $result_options );
		$this->select_field( 'error_code', __( 'Error code', 'ppok-ai-toolkit' ), $error_options );
		$this->select_field( 'mcp_client', __( 'Client', 'ppok-ai-toolkit' ), $client_options );

		$this->text_field( 'correlation_id', __( 'Correlation ID', 'ppok-ai-toolkit' ) );
		$this->text_field( 'actor_user_id', __( 'Actor user ID', 'ppok-ai-toolkit' ) );
		$this->text_field( 'target_post_id', __( 'Target post ID', 'ppok-ai-toolkit' ) );

		$this->date_field( 'from', __( 'From', 'ppok-ai-toolkit' ) );
		$this->date_field( 'to', __( 'To', 'ppok-ai-toolkit' ) );

		echo '<label style="display:flex;flex-direction:column;font-size:11px;color:#646970;text-transform:uppercase;letter-spacing:.04em">' . esc_html__( 'Reason contains', 'ppok-ai-toolkit' );
		printf(
			'<input type="search" name="s" value="%s" placeholder="%s" />',
			esc_attr( $search ),
			esc_attr__( 'free text…', 'ppok-ai-toolkit' )
		);
		echo '</label>';

		echo '</div>';

		echo '<div style="margin-top:1em;display:flex;gap:.5em;align-items:center">';
		submit_button( __( 'Filter', 'ppok-ai-toolkit' ), 'primary', '', false );
		printf(
			'<a class="button-link" href="%s">%s</a>',
			esc_url( $this->base_url ),
			esc_html__( 'Reset all filters', 'ppok-ai-toolkit' )
		);
		echo '</div>';

		echo '</form>';
	}

	private function preserve_query_args( array $names ): void {
		foreach ( $names as $name ) {
			if ( ! isset( $_GET[ $name ] ) ) {
				continue;
			}
			printf(
				'<input type="hidden" name="%s" value="%s" />',
				esc_attr( $name ),
				esc_attr( sanitize_text_field( (string) wp_unslash( $_GET[ $name ] ) ) )
			);
		}
	}

	private function select_field( string $name, string $label, array $options ): void {
		$current = isset( $_GET[ $name ] ) ? sanitize_text_field( (string) wp_unslash( $_GET[ $name ] ) ) : '';
		echo '<label style="display:flex;flex-direction:column;font-size:11px;color:#646970;text-transform:uppercase;letter-spacing:.04em">' . esc_html( $label );
		printf( '<select name="%s" style="width:100%%">', esc_attr( $name ) );
		echo '<option value="">' . esc_html__( '— Any —', 'ppok-ai-toolkit' ) . '</option>';
		foreach ( $options as $option ) {
			printf(
				'<option value="%s" %s>%s</option>',
				esc_attr( $option ),
				selected( $current, $option, false ),
				esc_html( $option )
			);
		}
		echo '</select></label>';
	}

	private function text_field( string $name, string $label ): void {
		$current = isset( $_GET[ $name ] ) ? sanitize_text_field( (string) wp_unslash( $_GET[ $name ] ) ) : '';
		echo '<label style="display:flex;flex-direction:column;font-size:11px;color:#646970;text-transform:uppercase;letter-spacing:.04em">' . esc_html( $label );
		printf(
			'<input type="text" name="%s" value="%s" />',
			esc_attr( $name ),
			esc_attr( $current )
		);
		echo '</label>';
	}

	private function date_field( string $name, string $label ): void {
		$current = isset( $_GET[ $name ] ) ? sanitize_text_field( (string) wp_unslash( $_GET[ $name ] ) ) : '';
		echo '<label style="display:flex;flex-direction:column;font-size:11px;color:#646970;text-transform:uppercase;letter-spacing:.04em">' . esc_html( $label );
		printf(
			'<input type="date" name="%s" value="%s" />',
			esc_attr( $name ),
			esc_attr( $current )
		);
		echo '</label>';
	}

	private function distinct_column_values( string $column ): array {
		global $wpdb;
		$allowed = array( 'ability_slug', 'mcp_client', 'error_code' );
		if ( ! in_array( $column, $allowed, true ) ) {
			return array();
		}
		$table = Event_Logger::table_name();
		// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared,WordPress.DB.DirectDatabaseQuery -- column is allowlisted; table comes from prefix helper.
		$rows = $wpdb->get_col(
			"SELECT DISTINCT {$column} FROM {$table} WHERE {$column} IS NOT NULL AND {$column} != '' ORDER BY {$column} ASC LIMIT 50"
		);
		return array_values( array_filter( (array) $rows ) );
	}

	private function render_detail( int $id ): void {
		global $wpdb;
		$table = Event_Logger::table_name();
		$row   = $wpdb->get_row(
			$wpdb->prepare( "SELECT * FROM {$table} WHERE id = %d", $id ),
			ARRAY_A
		);

		printf(
			'<p><a href="%s">&larr; %s</a></p>',
			esc_url( $this->base_url ),
			esc_html__( 'Back to all events', 'ppok-ai-toolkit' )
		);

		if ( ! $row ) {
			echo '<div class="notice notice-error"><p>' . esc_html__( 'Event not found.', 'ppok-ai-toolkit' ) . '</p></div>';
			return;
		}

		$this->render_summary_table( $row );

		$payload = array();
		if ( ! empty( $row['payload'] ) ) {
			$decoded = json_decode( (string) $row['payload'], true );
			if ( is_array( $decoded ) ) {
				$payload = $decoded;
			}
		}

		$this->render_diff_section( $payload );
		$this->render_payload_section( $payload, (string) ( $row['payload'] ?? '' ) );
	}

	private function render_summary_table( array $row ): void {
		echo '<h2>' . esc_html__( 'Summary', 'ppok-ai-toolkit' ) . '</h2>';
		echo '<table class="widefat striped" style="max-width:900px"><tbody>';

		$fields = array(
			'id'             => __( 'Event ID', 'ppok-ai-toolkit' ),
			'created_at'     => __( 'Created at (UTC)', 'ppok-ai-toolkit' ),
			'ability_slug'   => __( 'Ability', 'ppok-ai-toolkit' ),
			'result'         => __( 'Result', 'ppok-ai-toolkit' ),
			'error_code'     => __( 'Error code', 'ppok-ai-toolkit' ),
			'reason'         => __( 'Reason', 'ppok-ai-toolkit' ),
			'actor_user_id'  => __( 'Actor user ID', 'ppok-ai-toolkit' ),
			'target_post_id' => __( 'Target post ID', 'ppok-ai-toolkit' ),
			'correlation_id' => __( 'Correlation ID', 'ppok-ai-toolkit' ),
			'mcp_client'     => __( 'MCP client', 'ppok-ai-toolkit' ),
			'ip'             => __( 'IP', 'ppok-ai-toolkit' ),
			'duration_ms'    => __( 'Duration (ms)', 'ppok-ai-toolkit' ),
		);

		foreach ( $fields as $col => $label ) {
			$value = (string) ( $row[ $col ] ?? '' );
			printf(
				'<tr><th style="width:200px;text-align:left">%s</th><td><code>%s</code></td></tr>',
				esc_html( $label ),
				'' === $value ? '&mdash;' : esc_html( $value )
			);
		}
		echo '</tbody></table>';
	}

	private function render_diff_section( array $payload ): void {
		echo '<h2>' . esc_html__( 'Diff', 'ppok-ai-toolkit' ) . '</h2>';

		$diff = isset( $payload['diff'] ) && is_array( $payload['diff'] ) ? $payload['diff'] : null;
		if ( ! $diff ) {
			echo '<p class="description">' . esc_html__(
				'No structured diff captured for this event. Diff capture is populated by narrow write abilities (Phase 6+); rest-call rows currently log input_args only.',
				'ppok-ai-toolkit'
			) . '</p>';
			return;
		}

		echo '<table class="widefat striped" style="max-width:900px"><tbody>';
		if ( ! empty( $diff['revision_id'] ) ) {
			printf(
				'<tr><th style="width:200px;text-align:left">%s</th><td><code>%s</code></td></tr>',
				esc_html__( 'Revision ID', 'ppok-ai-toolkit' ),
				esc_html( (string) $diff['revision_id'] )
			);
		}
		if ( ! empty( $diff['before_content_sha1'] ) ) {
			printf(
				'<tr><th style="text-align:left">%s</th><td><code>%s</code> &rarr; <code>%s</code></td></tr>',
				esc_html__( 'Content sha1', 'ppok-ai-toolkit' ),
				esc_html( (string) $diff['before_content_sha1'] ),
				esc_html( (string) ( $diff['after_content_sha1'] ?? '' ) )
			);
		}
		echo '</tbody></table>';

		foreach ( array(
			'blocks_added'    => __( 'Blocks added', 'ppok-ai-toolkit' ),
			'blocks_removed'  => __( 'Blocks removed', 'ppok-ai-toolkit' ),
			'blocks_modified' => __( 'Blocks modified', 'ppok-ai-toolkit' ),
		) as $key => $heading ) {
			$entries = isset( $diff[ $key ] ) && is_array( $diff[ $key ] ) ? $diff[ $key ] : array();
			if ( empty( $entries ) ) {
				continue;
			}
			echo '<h3>' . esc_html( $heading ) . '</h3>';
			echo '<ol>';
			foreach ( $entries as $entry ) {
				$name     = (string) ( $entry['blockName'] ?? '' );
				$position = isset( $entry['position'] ) && is_array( $entry['position'] ) ? implode( '.', array_map( 'intval', $entry['position'] ) ) : '';
				printf(
					'<li><code>%s</code> at <code>%s</code>',
					esc_html( $name ),
					esc_html( $position )
				);

				if ( isset( $entry['excerpt'] ) ) {
					echo '<pre style="white-space:pre-wrap;background:#f6f7f7;padding:.5em">' . esc_html( (string) $entry['excerpt'] ) . '</pre>';
				}
				if ( isset( $entry['excerpt_before'] ) || isset( $entry['excerpt_after'] ) ) {
					echo '<p style="color:#646970">' . esc_html__( 'Before', 'ppok-ai-toolkit' ) . '</p>';
					echo '<pre style="white-space:pre-wrap;background:#fff0f0;padding:.5em">' . esc_html( (string) ( $entry['excerpt_before'] ?? '' ) ) . '</pre>';
					echo '<p style="color:#646970">' . esc_html__( 'After', 'ppok-ai-toolkit' ) . '</p>';
					echo '<pre style="white-space:pre-wrap;background:#f0fff0;padding:.5em">' . esc_html( (string) ( $entry['excerpt_after'] ?? '' ) ) . '</pre>';
				}
				if ( ! empty( $entry['attrs_changed'] ) && is_array( $entry['attrs_changed'] ) ) {
					echo '<p style="color:#646970">' . esc_html__( 'Attributes changed:', 'ppok-ai-toolkit' ) . ' <code>' . esc_html( implode( ', ', array_map( 'strval', $entry['attrs_changed'] ) ) ) . '</code></p>';
				}
				echo '</li>';
			}
			echo '</ol>';
		}
	}

	private function render_payload_section( array $payload, string $raw ): void {
		echo '<h2>' . esc_html__( 'Full payload', 'ppok-ai-toolkit' ) . '</h2>';

		if ( '' === $raw ) {
			echo '<p>&mdash;</p>';
			return;
		}

		$pretty = $payload ? (string) wp_json_encode( $payload, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES ) : $raw;
		echo '<pre style="white-space:pre-wrap;background:#f6f7f7;padding:1em;max-width:900px;overflow:auto">'
			. esc_html( $pretty )
			. '</pre>';
	}
}
