<?php
/**
 * Audit Admin Page.
 *
 * Tools → Content Auditor: run the batched scan, then filter / sort /
 * paginate the Keep-Refresh-Merge-Delete worklist and export it to CSV.
 * Read-only by design — it recommends, it never deletes.
 *
 * @package Platform\Helm\Modules\Content_Auditor
 */

declare( strict_types = 1 );

namespace Platform\Helm\Modules\Content_Auditor;

use Platform\Helm\Core\Assets;
use Platform\Helm\Core\Authorization;
use Platform\Helm\Modules\GSC\GscQueryStore;
use Platform\Helm\Core\LlmSettings;

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

final class AuditAdminPage {

	public const PAGE_SLUG   = 'platform-helm-content-auditor';
	public const PARENT_SLUG = 'platform-helm';

	public function __construct(
		private Assets $assets,
		private AuditStore $store,
		private ?GscQueryStore $query_store = null
	) {}

	public function register_hooks(): void {
		add_action( 'admin_menu', [ $this, 'register_menu' ], 47 );
	}

	public function register_menu(): void {
		if ( ! Authorization::is_master_admin() ) {
			return;
		}
		$hook = add_submenu_page(
			self::PARENT_SLUG,
			__( 'Content Auditor', 'platform-helm' ),
			__( 'Content Auditor', 'platform-helm' ),
			'manage_options',
			self::PAGE_SLUG,
			[ $this, 'render' ]
		);
		if ( $hook ) {
			add_action( 'load-' . $hook, [ $this, 'enqueue' ] );
		}
	}

	public function enqueue(): void {
		$this->assets->enqueue_content_auditor( [
			'ajaxUrl'      => admin_url( 'admin-ajax.php' ),
			'nonce'        => wp_create_nonce( AuditAjaxController::NONCE_ACTION ),
			'aiConfigured' => LlmSettings::is_configured() ? '1' : '',
			'briefAction'  => 'platform_helm_audit_brief',
		] );
	}

	private function badge( string $rec ): string {
		$labels = [
			AuditScorer::KEEP    => __( 'Keep', 'platform-helm' ),
			AuditScorer::REFRESH => __( 'Refresh', 'platform-helm' ),
			AuditScorer::MERGE   => __( 'Merge', 'platform-helm' ),
			AuditScorer::DELETE  => __( 'Delete', 'platform-helm' ),
		];
		$label = $labels[ $rec ] ?? $rec;
		return '<span class="ph-ca-badge ph-ca-' . esc_attr( $rec ) . '">' . esc_html( $label ) . '</span>';
	}

	public function render(): void {
		Authorization::require_master_admin();

		// phpcs:disable WordPress.Security.NonceVerification.Recommended
		$rec     = isset( $_GET['rec'] ) ? sanitize_key( wp_unslash( $_GET['rec'] ) ) : '';
		$orderby = isset( $_GET['orderby'] ) ? sanitize_key( wp_unslash( $_GET['orderby'] ) ) : 'impressions';
		$order   = isset( $_GET['order'] ) ? sanitize_key( wp_unslash( $_GET['order'] ) ) : 'desc';
		$paged   = isset( $_GET['paged'] ) ? max( 1, (int) $_GET['paged'] ) : 1;
		$hide_done = ! empty( $_GET['hide_done'] );
		// phpcs:enable WordPress.Security.NonceVerification.Recommended

		$counts    = $this->store->counts();
		$total     = $this->store->count_rows();
		$per_page  = 50;
		$result    = $this->store->query( $rec, $orderby, $order, $paged, $per_page, $hide_done );
		$rows      = $result['rows'];
		$found     = $result['total'];
		$max_pages = (int) ceil( $found / $per_page );

		// Refresh Intelligence: top GSC queries for the posts on this page.
		$top_queries = [];
		if ( $this->query_store && ! empty( $rows ) ) {
			$ids         = array_map( static fn( $r ) => (int) $r['post_id'], $rows );
			$top_queries = $this->query_store->top_queries_for_posts( $ids, 2 );
		}
		?>
		<div class="wrap ph-ca">
			<h1><?php esc_html_e( 'Content Auditor', 'platform-helm' ); ?></h1>
			<p class="ph-ca-lead">
				<?php esc_html_e( 'Scores every published post on Search Console traffic + on-page health into a Keep / Refresh / Merge / Delete worklist. It only recommends — it never changes or deletes anything. Always de-index and 301-redirect (via Yoast) before removing a post.', 'platform-helm' ); ?>
			</p>

			<div class="ph-ca-actions">
				<button type="button" class="button button-primary" id="ph-ca-run"><?php esc_html_e( 'Run / refresh audit', 'platform-helm' ); ?></button>
				<a class="button" href="<?php echo esc_url( wp_nonce_url( admin_url( 'admin-post.php?action=platform_helm_audit_export' ), AuditAjaxController::NONCE_ACTION . '_export' ) ); ?>"><?php esc_html_e( 'Export CSV', 'platform-helm' ); ?></a>
				<span class="ph-ca-msg" id="ph-ca-msg" aria-live="polite"></span>
			</div>
			<div class="ph-ca-progress" id="ph-ca-progress" hidden><div class="ph-ca-bar" id="ph-ca-bar"></div></div>

			<?php if ( 0 === $total ) : ?>
				<div class="ph-ca-card"><p><?php esc_html_e( 'No audit yet. Click “Run / refresh audit” to score your posts. The first run on a large site takes a few minutes — leave the tab open.', 'platform-helm' ); ?></p></div>
			<?php else : ?>
				<div class="ph-ca-summary">
					<?php
					foreach ( [ AuditScorer::KEEP, AuditScorer::REFRESH, AuditScorer::MERGE, AuditScorer::DELETE ] as $b ) :
						?>
						<a class="ph-ca-stat ph-ca-<?php echo esc_attr( $b ); ?>" href="<?php echo esc_url( add_query_arg( [ 'page' => self::PAGE_SLUG, 'rec' => $b ], admin_url( 'admin.php' ) ) ); ?>">
							<span class="ph-ca-num"><?php echo esc_html( number_format_i18n( $counts[ $b ] ?? 0 ) ); ?></span>
							<span class="ph-ca-lbl"><?php echo esc_html( ucfirst( $b ) ); ?></span>
						</a>
					<?php endforeach; ?>
				</div>

				<form method="get" class="ph-ca-filters">
					<input type="hidden" name="page" value="<?php echo esc_attr( self::PAGE_SLUG ); ?>" />
					<select name="rec">
						<option value=""<?php selected( $rec, '' ); ?>><?php esc_html_e( 'All recommendations', 'platform-helm' ); ?></option>
						<?php foreach ( [ AuditScorer::KEEP, AuditScorer::REFRESH, AuditScorer::MERGE, AuditScorer::DELETE ] as $b ) : ?>
							<option value="<?php echo esc_attr( $b ); ?>"<?php selected( $rec, $b ); ?>><?php echo esc_html( ucfirst( $b ) ); ?></option>
						<?php endforeach; ?>
					</select>
					<select name="orderby">
						<?php
						$cols = [ 'impressions' => __( 'Impressions', 'platform-helm' ), 'clicks' => __( 'Clicks', 'platform-helm' ), 'score' => __( 'Health score', 'platform-helm' ), 'word_count' => __( 'Word count', 'platform-helm' ), 'position' => __( 'Avg position', 'platform-helm' ), 'age_days' => __( 'Age', 'platform-helm' ) ];
						foreach ( $cols as $k => $lbl ) :
							?>
							<option value="<?php echo esc_attr( $k ); ?>"<?php selected( $orderby, $k ); ?>><?php echo esc_html( $lbl ); ?></option>
						<?php endforeach; ?>
					</select>
					<select name="order">
						<option value="desc"<?php selected( $order, 'desc' ); ?>><?php esc_html_e( 'High → low', 'platform-helm' ); ?></option>
						<option value="asc"<?php selected( $order, 'asc' ); ?>><?php esc_html_e( 'Low → high', 'platform-helm' ); ?></option>
					</select>
					<label class="ph-ca-hidedone"><input type="checkbox" name="hide_done" value="1"<?php checked( $hide_done ); ?> /> <?php esc_html_e( 'Hide done', 'platform-helm' ); ?></label>
					<button type="submit" class="button"><?php esc_html_e( 'Apply', 'platform-helm' ); ?></button>
				</form>

				<div class="ph-ca-bulkbar">
					<select id="ph-ca-bulk">
						<option value=""><?php esc_html_e( 'Bulk action on selected…', 'platform-helm' ); ?></option>
						<option value="mark_done"><?php esc_html_e( 'Mark as done', 'platform-helm' ); ?></option>
						<option value="mark_open"><?php esc_html_e( 'Mark as not done', 'platform-helm' ); ?></option>
						<option value="noindex"><?php esc_html_e( 'Set to noindex (de-index)', 'platform-helm' ); ?></option>
						<option value="trash"><?php esc_html_e( 'Move to Trash (reversible)', 'platform-helm' ); ?></option>
					</select>
					<input type="text" id="ph-ca-redirect" class="ph-ca-redirect-input" placeholder="<?php esc_attr_e( 'Optional 301 target for Trash, e.g. /hub-post/', 'platform-helm' ); ?>" />
					<button type="button" class="button" id="ph-ca-apply"><?php esc_html_e( 'Apply', 'platform-helm' ); ?></button>
					<span class="ph-ca-selcount" id="ph-ca-selcount"></span>
					<span class="ph-ca-msg" id="ph-ca-bulkmsg" aria-live="polite"></span>
				</div>
				<p class="ph-ca-hint">
					<?php
					echo esc_html(
						Redirects::available()
							? __( 'Redirect field active: a 301 to that target is created in Yoast for each selected post before it is trashed. Leave blank to trash without a redirect.', 'platform-helm' )
							: __( 'Yoast Premium redirect manager not detected — the redirect field will be ignored. Trash still works; add redirects manually.', 'platform-helm' )
					);
					?>
				</p>

				<table class="widefat striped ph-ca-table">
					<thead>
						<tr>
							<td class="check-column"><input type="checkbox" id="ph-ca-selectall" /></td>
							<th><?php esc_html_e( 'Post', 'platform-helm' ); ?></th>
							<th><?php esc_html_e( 'Action', 'platform-helm' ); ?></th>
							<th><?php esc_html_e( 'Clicks', 'platform-helm' ); ?></th>
							<th><?php esc_html_e( 'Impr.', 'platform-helm' ); ?></th>
							<th><?php esc_html_e( 'CTR', 'platform-helm' ); ?></th>
							<th><?php esc_html_e( 'Pos.', 'platform-helm' ); ?></th>
							<th><?php esc_html_e( 'Words', 'platform-helm' ); ?></th>
							<th><?php esc_html_e( 'Img', 'platform-helm' ); ?></th>
							<th><?php esc_html_e( 'Top query (rank)', 'platform-helm' ); ?></th>
							<th><?php esc_html_e( 'Why', 'platform-helm' ); ?></th>
						</tr>
					</thead>
					<tbody>
						<?php if ( empty( $rows ) ) : ?>
							<tr><td colspan="11"><?php esc_html_e( 'No posts match this filter.', 'platform-helm' ); ?></td></tr>
						<?php else : ?>
							<?php
							foreach ( $rows as $r ) :
								$is_done = ! empty( $r['handled'] );
								?>
								<tr class="<?php echo $is_done ? 'ph-ca-done-row' : ''; ?>">
									<th scope="row" class="check-column"><input type="checkbox" class="ph-ca-cb" value="<?php echo esc_attr( (string) (int) $r['post_id'] ); ?>" /></th>
									<td>
										<a href="<?php echo esc_url( (string) get_edit_post_link( (int) $r['post_id'] ) ); ?>"><?php echo esc_html( (string) $r['title'] ); ?></a>
										<?php if ( $is_done ) : ?><span class="ph-ca-doneflag"><?php esc_html_e( '✓ done', 'platform-helm' ); ?></span><?php endif; ?>
										<div class="ph-ca-url"><a href="<?php echo esc_url( (string) $r['url'] ); ?>" target="_blank" rel="noopener"><?php echo esc_html( (string) $r['url'] ); ?></a></div>
									</td>
									<td>
										<?php echo $this->badge( (string) $r['recommendation'] ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
										<div><a class="ph-ca-edit" href="<?php echo esc_url( (string) get_edit_post_link( (int) $r['post_id'] ) ); ?>"><?php esc_html_e( 'Edit →', 'platform-helm' ); ?></a></div>
										<?php if ( LlmSettings::is_configured() ) : ?>
											<div><button type="button" class="button button-small ph-ca-brief" data-id="<?php echo esc_attr( (string) (int) $r['post_id'] ); ?>"><?php esc_html_e( 'AI brief', 'platform-helm' ); ?></button></div>
										<?php endif; ?>
									</td>
									<td><?php echo esc_html( number_format_i18n( (int) $r['clicks'] ) ); ?></td>
									<td><?php echo esc_html( number_format_i18n( (int) $r['impressions'] ) ); ?></td>
									<td><?php echo esc_html( ( (int) $r['impressions'] > 0 ) ? round( (float) $r['ctr'] * 100, 1 ) . '%' : '—' ); ?></td>
									<td><?php echo esc_html( ( (float) $r['position'] > 0 ) ? number_format( (float) $r['position'], 1 ) : '—' ); ?></td>
									<td><?php echo esc_html( number_format_i18n( (int) $r['word_count'] ) ); ?></td>
									<td><?php echo ( (int) $r['has_image'] ) ? '✓' : '<span class="ph-ca-no">✗</span>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?></td>
									<td class="ph-ca-topq">
										<?php
										$pq = $top_queries[ (int) $r['post_id'] ] ?? [];
										if ( empty( $pq ) ) {
											echo '<span class="ph-ca-no">—</span>';
										} else {
											$bits = [];
											foreach ( $pq as $q ) {
												$bits[] = sprintf(
													'<span class="ph-ca-q">%s</span> <span class="ph-ca-qpos">#%s</span>',
													esc_html( (string) $q['query'] ),
													esc_html( number_format( (float) $q['position'], 1 ) )
												);
											}
											echo implode( '<br />', $bits ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
										}
										?>
									</td>
									<td class="ph-ca-why"><?php echo esc_html( (string) $r['reasons'] ); ?></td>
								</tr>
							<?php endforeach; ?>
						<?php endif; ?>
					</tbody>
				</table>

				<?php if ( $max_pages > 1 ) : ?>
					<div class="tablenav"><div class="tablenav-pages">
						<?php
						echo wp_kses_post( paginate_links( [
							'base'      => add_query_arg( 'paged', '%#%' ),
							'format'    => '',
							'current'   => $paged,
							'total'     => $max_pages,
							'prev_text' => '‹',
							'next_text' => '›',
						] ) );
						?>
					</div></div>
				<?php endif; ?>
			<?php endif; ?>
		</div>
		<?php
	}
}
