<?php
/**
 * Admin page — pairing handshake with the relay, connector URL display,
 * tools list, activity log, snapshot restore.
 *
 * Sits inside the shared "PC Designs" parent menu via pcd_admin_products.
 */

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

class PCD_PC_Admin {

	const PAGE_SLUG = 'pressconduit';

	public static function init(): void {
		add_filter( 'pcd_admin_products', [ __CLASS__, 'register_product' ] );
		add_action( 'admin_menu', [ __CLASS__, 'register_menu' ], 20 );
		add_action( 'admin_menu', [ __CLASS__, 'remove_default_submenu' ], 999 );
		add_action( 'admin_post_pcd_pc_pair', [ __CLASS__, 'handle_pair' ] );
		add_action( 'admin_post_pcd_pc_unpair', [ __CLASS__, 'handle_unpair' ] );
		add_action( 'admin_post_pcd_pc_connect', [ __CLASS__, 'handle_connect' ] );
		add_action( 'admin_post_pcd_pc_rotate_token', [ __CLASS__, 'handle_rotate_token' ] );
		if ( pcd_pc_is_direct_build() ) {
			add_action( 'admin_post_pcd_pc_check_updates', [ __CLASS__, 'handle_check_updates' ] );
			add_action( 'admin_post_pcd_pc_auto_update', [ __CLASS__, 'handle_auto_update' ] );
		}
		add_action( 'admin_post_pcd_pc_set_user', [ __CLASS__, 'handle_set_user' ] );
		add_action( 'admin_post_pcd_pc_restore', [ __CLASS__, 'handle_restore' ] );
		add_action( 'admin_post_pcd_pc_file_access', [ __CLASS__, 'handle_file_access' ] );
		if ( pcd_pc_is_direct_build() ) {
			add_action( 'admin_post_pcd_pc_activate_license', [ __CLASS__, 'handle_activate_license' ] );
			add_action( 'admin_post_pcd_pc_deactivate_license', [ __CLASS__, 'handle_deactivate_license' ] );
			add_action( 'admin_post_pcd_pc_dismiss_license_notice', [ __CLASS__, 'handle_dismiss_license_notice' ] );
			add_action( 'admin_notices', [ __CLASS__, 'license_notice' ] );
		}
		add_action( 'admin_enqueue_scripts', [ __CLASS__, 'enqueue_assets' ] );
		add_action( 'admin_enqueue_scripts', [ __CLASS__, 'menu_icon_size_style' ] );
	}

	/**
	 * Constrain the PC Designs parent menu icon to wp-admin's 18×18 slot.
	 * Without this the native-resolution PNG (~500px) renders enormous in
	 * the sidebar.
	 */
	public static function menu_icon_size_style(): void {
		$icon = self::menu_icon();
		if ( 0 === strpos( $icon, 'dashicons-' ) ) {
			return;
		}
		$css = '#adminmenu #toplevel_page_pc-designs .wp-menu-image { overflow: visible; }'
			. '#adminmenu #toplevel_page_pc-designs .wp-menu-image img {'
			. ' width: 18px; height: 18px; margin: 7px auto 0; padding: 0; opacity: 1;'
			. ' object-fit: contain; object-position: center; display: block; }';
		wp_register_style( 'pcd-pc-menu-icon', false, [], PCD_PC_VERSION );
		wp_enqueue_style( 'pcd-pc-menu-icon' );
		wp_add_inline_style( 'pcd-pc-menu-icon', $css );
	}

	public static function register_product( array $products ): array {
		// Register ONLY ourselves. Each PC Designs plugin self-registers into the
		// shared `pcd_admin_products` menu when it's actually installed/active, so
		// the cross-product launcher only lists real, present siblings. (Divi
		// Conduit and Bricks Conduit are retired and folded into PressConduit;
		// hardcoding them here made them show up as permanent "Not installed"
		// entries even though there's nothing to install.)
		$products['pressconduit'] = [
			'slug'  => 'pressconduit',
			'title' => __( 'PressConduit', 'pressconduit' ),
			'page'  => self::PAGE_SLUG,
			'file'  => 'pressconduit/pressconduit.php',
		];
		return $products;
	}

	public static function register_menu(): void {
		$parent_slug   = 'pc-designs';
		$parent_exists = false;

		global $menu;
		if ( is_array( $menu ) ) {
			foreach ( $menu as $item ) {
				if ( isset( $item[2] ) && $item[2] === $parent_slug ) {
					$parent_exists = true;
					break;
				}
			}
		}

		if ( ! $parent_exists ) {
			add_menu_page( 'PC Designs', 'PC Designs', 'manage_options', $parent_slug, [ __CLASS__, 'render_page' ], self::menu_icon(), 59 );
		} else {
			// Another PCD plugin already registered the parent — make sure the
			// shared brand icon wins over whatever it set (often the dashicons gear).
			global $menu;
			if ( is_array( $menu ) ) {
				$icon = self::menu_icon();
				foreach ( $menu as $index => $item ) {
					if ( isset( $item[2] ) && $item[2] === $parent_slug ) {
						$menu[ $index ][6] = $icon;
						break;
					}
				}
			}
		}

		add_submenu_page(
			$parent_slug,
			__( 'PressConduit', 'pressconduit' ),
			__( 'PressConduit', 'pressconduit' ),
			'manage_options',
			self::PAGE_SLUG,
			[ __CLASS__, 'render_page' ]
		);
	}

	public static function remove_default_submenu(): void {
		remove_submenu_page( 'pc-designs', 'pc-designs' );
	}

	/**
	 * URL of the shared "PC Designs" parent menu icon. Mirrors the prefer-
	 * png-then-svg-then-dashicon fallback used in the PCD plugin template so
	 * every PCD product shows the same mark in wp-admin.
	 */
	private static function menu_icon(): string {
		if ( file_exists( PCD_PC_DIR . 'assets/menu-icon.png' ) ) {
			return PCD_PC_URL . 'assets/menu-icon.png';
		}
		if ( file_exists( PCD_PC_DIR . 'assets/menu-icon.svg' ) ) {
			return PCD_PC_URL . 'assets/menu-icon.svg';
		}
		return 'dashicons-admin-generic';
	}

	public static function enqueue_assets( string $hook_suffix ): void {
		if ( false === strpos( $hook_suffix, self::PAGE_SLUG ) ) {
			return;
		}
		$css = PCD_PC_DIR . 'assets/admin.css';
		if ( file_exists( $css ) ) {
			wp_enqueue_style(
				'pcd-pc-admin',
				PCD_PC_URL . 'assets/admin.css',
				[],
				(string) filemtime( $css )
			);
		}

		// Inline JS for the cross-product menu dropdown toggle, enqueued (not printed).
		$js = '(function(){var toggle=document.getElementById("pcd-pc-products-toggle");var list=document.getElementById("pcd-pc-products-list");if(!toggle||!list)return;toggle.addEventListener("click",function(){var expanded=toggle.getAttribute("aria-expanded")==="true";toggle.setAttribute("aria-expanded",expanded?"false":"true");list.hidden=expanded;});document.addEventListener("click",function(e){if(!list.hidden&&!toggle.contains(e.target)&&!list.contains(e.target)){list.hidden=true;toggle.setAttribute("aria-expanded","false");}});})();';
		wp_register_script( 'pcd-pc-admin', false, [], PCD_PC_VERSION, true );
		wp_enqueue_script( 'pcd-pc-admin' );
		wp_add_inline_script( 'pcd-pc-admin', $js );
	}

	// ------------------------------------------------------------------
	// Form handlers
	// ------------------------------------------------------------------

	public static function handle_pair(): void {
		check_admin_referer( 'pcd_pc_pair' );
		if ( ! current_user_can( 'manage_options' ) ) {
			wp_die( 'Forbidden' );
		}
		$existing = isset( $_POST['existing_connector_url'] ) ? esc_url_raw( wp_unslash( $_POST['existing_connector_url'] ) ) : '';
		$ok = PCD_PC_Pair::pair( (string) $existing );
		wp_safe_redirect( add_query_arg( [
			'page' => self::PAGE_SLUG,
			$ok ? 'paired' : 'pair_failed' => '1',
		], admin_url( 'admin.php' ) ) );
		exit;
	}

	/**
	 * "Connect to Conduit" button — ensures the site is paired with the relay,
	 * then redirects the user's browser to the relay's /connect page (which
	 * sets a cookie and shows the universal MCP URL). Form opens in a new tab
	 * via target="_blank" so the user can copy the URL there and return here.
	 */
	public static function handle_connect(): void {
		check_admin_referer( 'pcd_pc_connect' );
		if ( ! current_user_can( 'manage_options' ) ) {
			wp_die( 'Forbidden' );
		}
		$ok = PCD_PC_Pair::is_paired() ? true : PCD_PC_Pair::pair();
		if ( ! $ok ) {
			wp_die( esc_html( __( 'Could not pair with the Conduit relay: ', 'pressconduit' ) . PCD_PC_Pair::last_error() ) );
		}
		$url = PCD_PC_Pair::connect_url();
		if ( ! $url ) {
			wp_die( esc_html__( 'Backend URL is not configured.', 'pressconduit' ) );
		}
		// The target is the external relay, so allow its host for a safe redirect.
		add_filter( 'allowed_redirect_hosts', function ( $hosts ) use ( $url ) {
			$host = wp_parse_url( $url, PHP_URL_HOST );
			if ( $host ) {
				$hosts[] = $host;
			}
			return $hosts;
		} );
		wp_safe_redirect( $url );
		exit;
	}

	public static function handle_unpair(): void {
		check_admin_referer( 'pcd_pc_unpair' );
		if ( ! current_user_can( 'manage_options' ) ) {
			wp_die( 'Forbidden' );
		}
		PCD_PC_Pair::reset();
		wp_safe_redirect( add_query_arg( [ 'page' => self::PAGE_SLUG, 'unpaired' => '1' ], admin_url( 'admin.php' ) ) );
		exit;
	}

	public static function handle_check_updates(): void {
		check_admin_referer( 'pcd_pc_check_updates' );
		if ( ! current_user_can( 'update_plugins' ) ) {
			wp_die( 'Forbidden' );
		}

		$manifest = PCD_PC_Updater::force_check();
		$args     = [ 'page' => self::PAGE_SLUG, 'tab' => 'settings' ];

		if ( $manifest ) {
			$current = defined( 'PCD_PC_VERSION' ) ? PCD_PC_VERSION : '0.0.0';
			if ( version_compare( $current, $manifest['version'] ) < 0 ) {
				$args['update_available'] = $manifest['version'];
			} else {
				$args['on_latest'] = '1';
			}
		} else {
			$args['check_failed'] = '1';
		}

		wp_safe_redirect( add_query_arg( $args, admin_url( 'admin.php' ) ) );
		exit;
	}

	public static function handle_auto_update(): void {
		check_admin_referer( 'pcd_pc_auto_update' );
		if ( ! current_user_can( 'update_plugins' ) ) {
			wp_die( 'Forbidden' );
		}
		$enabled = ! empty( $_POST['auto_update'] );
		update_option( PCD_PC_Updater::OPTION_AUTO_UPDATE, $enabled ? 1 : 0 );
		wp_safe_redirect( add_query_arg( [ 'page' => self::PAGE_SLUG, 'tab' => 'settings', 'auto_update' => $enabled ? 'on' : 'off' ], admin_url( 'admin.php' ) ) );
		exit;
	}

	public static function handle_rotate_token(): void {
		check_admin_referer( 'pcd_pc_rotate_token' );
		if ( ! current_user_can( 'manage_options' ) ) {
			wp_die( 'Forbidden' );
		}
		PCD_PC_Auth::rotate_token();
		// Token rotated — existing pairing is stale; re-pair to push the new token to the relay.
		PCD_PC_Pair::reset();
		wp_safe_redirect( add_query_arg( [ 'page' => self::PAGE_SLUG, 'rotated' => '1' ], admin_url( 'admin.php' ) ) );
		exit;
	}

	public static function handle_set_user(): void {
		check_admin_referer( 'pcd_pc_set_user' );
		if ( ! current_user_can( 'manage_options' ) ) {
			wp_die( 'Forbidden' );
		}
		$user_id = isset( $_POST['user_id'] ) ? absint( wp_unslash( $_POST['user_id'] ) ) : 0;
		if ( $user_id && get_userdata( $user_id ) ) {
			PCD_PC_Auth::set_linked_user_id( $user_id );
		}
		wp_safe_redirect( add_query_arg( [ 'page' => self::PAGE_SLUG, 'user_set' => '1' ], admin_url( 'admin.php' ) ) );
		exit;
	}

	public static function handle_restore(): void {
		check_admin_referer( 'pcd_pc_restore' );
		if ( ! current_user_can( 'manage_options' ) ) {
			wp_die( 'Forbidden' );
		}
		$id = isset( $_POST['snapshot_id'] ) ? absint( wp_unslash( $_POST['snapshot_id'] ) ) : 0;
		if ( $id ) {
			PCD_PC_Snapshot::restore( $id );
		}
		wp_safe_redirect( add_query_arg( [ 'page' => self::PAGE_SLUG, 'tab' => 'snapshots', 'restored' => '1' ], admin_url( 'admin.php' ) ) );
		exit;
	}

	public static function handle_file_access(): void {
		check_admin_referer( 'pcd_pc_file_access' );
		if ( ! current_user_can( 'manage_options' ) ) {
			wp_die( 'Forbidden' );
		}
		$enabled = ! empty( $_POST['allow_file_tools'] );
		update_option( 'pcd_pc_allow_file_tools', $enabled ? 1 : 0 );
		wp_safe_redirect( add_query_arg( [ 'page' => self::PAGE_SLUG, 'tab' => 'settings', 'file_access' => $enabled ? 'on' : 'off' ], admin_url( 'admin.php' ) ) );
		exit;
	}

	public static function handle_activate_license(): void {
		check_admin_referer( 'pcd_pc_activate_license' );
		if ( ! current_user_can( 'manage_options' ) ) {
			wp_die( 'Forbidden' );
		}
		$key = isset( $_POST['license_key'] ) ? sanitize_text_field( wp_unslash( $_POST['license_key'] ) ) : '';
		$ok  = PCD_PC_License::activate( $key );
		wp_safe_redirect( add_query_arg( [
			'page' => self::PAGE_SLUG,
			'tab'  => 'settings',
			$ok ? 'license_activated' : 'license_failed' => '1',
		], admin_url( 'admin.php' ) ) );
		exit;
	}

	public static function handle_deactivate_license(): void {
		check_admin_referer( 'pcd_pc_deactivate_license' );
		if ( ! current_user_can( 'manage_options' ) ) {
			wp_die( 'Forbidden' );
		}
		PCD_PC_License::deactivate();
		wp_safe_redirect( add_query_arg( [ 'page' => self::PAGE_SLUG, 'tab' => 'settings', 'license_deactivated' => '1' ], admin_url( 'admin.php' ) ) );
		exit;
	}

	/**
	 * Admin-wide nudge to activate or buy a license. Shows ONLY when the relay
	 * confirms this site is genuinely unlicensed — grandfathered and licensed
	 * sites never see it. Dismissible for two weeks.
	 */
	public static function license_notice(): void {
		if ( ! current_user_can( 'manage_options' ) ) {
			return;
		}
		// Don't nag on our own settings page — the key field is right there.
		if ( isset( $_GET['page'] ) && self::PAGE_SLUG === sanitize_key( wp_unslash( $_GET['page'] ) ) ) { // phpcs:ignore WordPress.Security.NonceVerification
			return;
		}
		if ( get_transient( 'pcd_pc_license_notice_dismissed' ) ) {
			return;
		}
		if ( ! PCD_PC_License::needs_license() ) {
			return;
		}

		$settings_url = add_query_arg( [ 'page' => self::PAGE_SLUG, 'tab' => 'settings' ], admin_url( 'admin.php' ) );
		$buy_url      = PCD_PC_License::purchase_url();
		$dismiss_url  = wp_nonce_url( admin_url( 'admin-post.php?action=pcd_pc_dismiss_license_notice' ), 'pcd_pc_dismiss_license_notice' );
		?>
		<div class="notice notice-warning">
			<p style="font-size:13px;margin-bottom:6px;">
				<strong><?php esc_html_e( 'PressConduit isn\'t licensed on this site yet.', 'pressconduit' ); ?></strong>
				<?php esc_html_e( 'Add your license key to unlock everything, or pick a plan to get one.', 'pressconduit' ); ?>
			</p>
			<p>
				<a href="<?php echo esc_url( $settings_url ); ?>" class="button button-primary"><?php esc_html_e( 'Enter license key', 'pressconduit' ); ?></a>
				<a href="<?php echo esc_url( $buy_url ); ?>" class="button" target="_blank" rel="noopener"><?php esc_html_e( 'View plans', 'pressconduit' ); ?></a>
				<a href="<?php echo esc_url( $dismiss_url ); ?>" style="margin-left:8px;text-decoration:none;color:#646970;"><?php esc_html_e( 'Dismiss for 2 weeks', 'pressconduit' ); ?></a>
			</p>
		</div>
		<?php
	}

	public static function handle_dismiss_license_notice(): void {
		check_admin_referer( 'pcd_pc_dismiss_license_notice' );
		if ( ! current_user_can( 'manage_options' ) ) {
			wp_die( 'Forbidden' );
		}
		set_transient( 'pcd_pc_license_notice_dismissed', 1, 14 * DAY_IN_SECONDS );
		wp_safe_redirect( wp_get_referer() ? wp_get_referer() : admin_url() );
		exit;
	}

	// ------------------------------------------------------------------
	// Render
	// ------------------------------------------------------------------

	public static function render_page(): void {
		$active_tab = isset( $_GET['tab'] ) ? sanitize_key( wp_unslash( $_GET['tab'] ) ) : 'connection'; // phpcs:ignore WordPress.Security.NonceVerification

		// Opportunistically refresh the update transient on each plugin admin page load.
		// Cheap (cached for 15 min), but ensures the WP Updates UI is never stale when
		// someone is actively in the plugin's admin.
		if ( class_exists( 'PCD_PC_Updater' ) && ! wp_doing_ajax() ) {
			wp_update_plugins();
		}

		echo '<div class="wrap">';
		echo '<h1 class="screen-reader-text">' . esc_html__( 'PressConduit', 'pressconduit' ) . '</h1>';

		self::render_notices();

		echo '<div class="pcd-admin-shell">';
		self::render_header();
		self::render_tabs( $active_tab );

		echo '<div class="pcd-admin-content">';
		self::render_hero( $active_tab );
		switch ( $active_tab ) {
			case 'activity':
				self::render_activity();
				break;
			case 'snapshots':
				self::render_snapshots();
				break;
			case 'tools':
				self::render_tools();
				break;
			case 'settings':
				self::render_settings();
				break;
			default:
				self::render_connection();
		}
		echo '</div></div></div>';
	}

	private static function render_header(): void {
		$products      = self::get_pcd_products();
		$other         = array_values( array_filter( $products, function ( $p ) {
			return 'pressconduit' !== $p['slug'];
		} ) );
		$has_others    = ! empty( $other );

		?>
		<header class="pcd-admin-header">
			<div class="pcd-admin-header-title">
				<?php if ( $has_others ) : ?>
					<button type="button" class="pcd-admin-products-toggle" id="pcd-pc-products-toggle" aria-expanded="false" aria-controls="pcd-pc-products-list">
						<span class="pcd-admin-title-wrap">
							<span class="pcd-admin-title"><?php esc_html_e( 'PressConduit', 'pressconduit' ); ?></span>
							<span class="pcd-admin-badge">v<?php echo esc_html( PCD_PC_VERSION ); ?></span>
						</span>
						<span class="dashicons dashicons-arrow-down-alt2 pcd-admin-products-chevron" aria-hidden="true"></span>
					</button>
					<ul id="pcd-pc-products-list" class="pcd-admin-products-list" role="menu" hidden>
						<li class="pcd-admin-products-list-title" role="none">
							<span class="pcd-admin-products-list-title-text"><?php esc_html_e( 'My Plugins', 'pressconduit' ); ?></span>
						</li>
						<?php foreach ( $other as $product ) : ?>
							<li role="none">
								<?php if ( 'active' === $product['status'] && ! empty( $product['url'] ) ) : ?>
									<a href="<?php echo esc_url( $product['url'] ); ?>" role="menuitem" class="pcd-admin-products-item"><?php echo esc_html( (string) $product['title'] ); ?></a>
								<?php elseif ( 'inactive' === $product['status'] ) : ?>
									<a href="<?php echo esc_url( admin_url( 'plugins.php' ) ); ?>" role="menuitem" class="pcd-admin-products-item"><?php echo esc_html( $product['title'] . ' (' . __( 'Inactive', 'pressconduit' ) . ')' ); ?></a>
								<?php else : ?>
									<span class="pcd-admin-products-item pcd-admin-products-item--muted"><?php echo esc_html( $product['title'] . ' (' . __( 'Not installed', 'pressconduit' ) . ')' ); ?></span>
								<?php endif; ?>
							</li>
						<?php endforeach; ?>
					</ul>
				<?php else : ?>
					<span class="pcd-admin-title-wrap">
						<span class="pcd-admin-title"><?php esc_html_e( 'PressConduit', 'pressconduit' ); ?></span>
						<span class="pcd-admin-badge">v<?php echo esc_html( PCD_PC_VERSION ); ?></span>
					</span>
				<?php endif; ?>
			</div>
			<div class="pcd-admin-header-actions">
				<?php if ( PCD_PC_Pair::is_paired() ) : ?>
					<span class="pcd-admin-header-icon" title="<?php esc_attr_e( 'Paired with the relay', 'pressconduit' ); ?>" style="color:#1b9c7a">
						<span class="dashicons dashicons-yes-alt"></span>
					</span>
				<?php endif; ?>
				<a href="https://pcdesignstx.com" target="_blank" rel="noopener" class="pcd-admin-header-icon" title="<?php esc_attr_e( 'PC Designs', 'pressconduit' ); ?>">
					<span class="dashicons dashicons-external"></span>
				</a>
			</div>
		</header>
		<?php
	}

	/**
	 * Read the shared PCD product registry (plugins implementing the same shell).
	 */
	private static function get_pcd_products(): array {
		if ( ! function_exists( 'get_plugins' ) ) {
			require_once ABSPATH . 'wp-admin/includes/plugin.php';
		}
		$map = apply_filters( 'pcd_admin_products', [] );
		if ( ! is_array( $map ) ) {
			$map = [];
		}
		$list = [];
		foreach ( $map as $slug => $info ) {
			$list[ $slug ] = [
				'slug'        => $slug,
				'title'       => $info['title'] ?? $slug,
				'status'      => 'notinstalled',
				'url'         => null,
				'plugin_file' => null,
			];
		}
		foreach ( get_plugins() as $plugin_file => $_data ) {
			$slug = dirname( $plugin_file );
			if ( '.' === $slug ) {
				$slug = strtok( $plugin_file, '/' );
			}
			if ( ! isset( $list[ $slug ] ) ) {
				continue;
			}
			$list[ $slug ]['status']      = is_plugin_active( $plugin_file ) ? 'active' : 'inactive';
			$list[ $slug ]['plugin_file'] = $plugin_file;
			if ( $list[ $slug ]['status'] === 'active' && ! empty( $map[ $slug ]['page'] ) ) {
				$list[ $slug ]['url'] = admin_url( 'admin.php?page=' . $map[ $slug ]['page'] );
			} elseif ( $list[ $slug ]['status'] === 'inactive' ) {
				$list[ $slug ]['url'] = admin_url( 'plugins.php' );
			}
		}
		return array_values( $list );
	}

	private static function render_hero( string $tab ): void {
		$heroes = [
			'connection' => [
				'title' => __( 'Connect Your AI', 'pressconduit' ),
				'desc'  => __( 'Pair this site, then paste the connector URL into Claude, ChatGPT, or Cursor. Auth happens automatically.', 'pressconduit' ),
			],
			'tools' => [
				'title' => __( 'Tool Surface', 'pressconduit' ),
				'desc'  => __( 'Every capability your AI assistant gets when it talks to this site.', 'pressconduit' ),
			],
			'activity' => [
				'title' => __( 'Activity', 'pressconduit' ),
				'desc'  => __( 'Every tool call, timestamped, with status and timing. The audit trail.', 'pressconduit' ),
			],
			'snapshots' => [
				'title' => __( 'Snapshots & Undo', 'pressconduit' ),
				'desc'  => __( 'Every mutation captures a snapshot so you can roll back AI changes with one click.', 'pressconduit' ),
			],
			'settings' => [
				'title' => __( 'Settings', 'pressconduit' ),
				'desc'  => __( 'Linked WordPress user, secrets, and update controls.', 'pressconduit' ),
			],
		];
		$h         = $heroes[ $tab ] ?? $heroes['connection'];
		$icon_path = PCD_PC_DIR . 'assets/icon.svg';
		$has_icon  = file_exists( $icon_path );
		?>
		<section class="pcd-admin-hero-card">
			<div class="pcd-admin-hero-copy">
				<div class="pcd-admin-hero-media">
					<?php if ( $has_icon ) : ?>
						<img src="<?php echo esc_url( PCD_PC_URL . 'assets/icon.svg' ); ?>" alt="" width="38" height="38" />
					<?php else : ?>
						<span class="dashicons dashicons-admin-links"></span>
					<?php endif; ?>
				</div>
				<div>
					<h2><?php echo esc_html( $h['title'] ); ?></h2>
					<p><?php echo esc_html( $h['desc'] ); ?></p>
				</div>
			</div>
		</section>
		<?php
	}

	private static function render_notices(): void {
		// phpcs:disable WordPress.Security.NonceVerification.Recommended
		if ( isset( $_GET['paired'] ) ) {
			echo '<div class="notice notice-success is-dismissible"><p>' . esc_html__( 'Site paired with the relay. The connector URL is below — paste it into Claude.', 'pressconduit' ) . '</p></div>';
		}
		if ( isset( $_GET['pair_failed'] ) ) {
			$err = PCD_PC_Pair::last_error();
			echo '<div class="notice notice-error is-dismissible"><p>' . esc_html__( 'Pairing failed: ', 'pressconduit' ) . esc_html( $err ) . '</p></div>';
		}
		if ( isset( $_GET['unpaired'] ) ) {
			echo '<div class="notice notice-info is-dismissible"><p>' . esc_html__( 'Local pairing cleared. Re-pair to issue a fresh connector URL.', 'pressconduit' ) . '</p></div>';
		}
		if ( isset( $_GET['rotated'] ) ) {
			echo '<div class="notice notice-info is-dismissible"><p>' . esc_html__( 'Token rotated. Re-pair to push the new token to the relay.', 'pressconduit' ) . '</p></div>';
		}
		if ( isset( $_GET['update_available'] ) ) {
			$v = sanitize_text_field( wp_unslash( $_GET['update_available'] ) );
			/* translators: %s: the available plugin version number. */
			echo '<div class="notice notice-success is-dismissible"><p>' . esc_html( sprintf( __( 'PressConduit v%s is available. Visit Dashboard → Updates to install.', 'pressconduit' ), $v ) ) . ' <a href="' . esc_url( admin_url( 'update-core.php' ) ) . '">' . esc_html__( 'Go to Updates', 'pressconduit' ) . ' →</a></p></div>';
		}
		if ( isset( $_GET['on_latest'] ) ) {
			echo '<div class="notice notice-info is-dismissible"><p>' . esc_html__( 'You are on the latest version of PressConduit.', 'pressconduit' ) . '</p></div>';
		}
		if ( isset( $_GET['check_failed'] ) ) {
			echo '<div class="notice notice-error is-dismissible"><p>' . esc_html__( 'Update check failed. The backend may be unreachable.', 'pressconduit' ) . '</p></div>';
		}
		if ( isset( $_GET['auto_update'] ) ) {
			$on = 'on' === sanitize_text_field( wp_unslash( $_GET['auto_update'] ) );
			echo '<div class="notice notice-success is-dismissible"><p>' . esc_html( $on ? __( 'Automatic updates enabled for PressConduit.', 'pressconduit' ) : __( 'Automatic updates disabled for PressConduit.', 'pressconduit' ) ) . '</p></div>';
		}
		if ( isset( $_GET['license_activated'] ) ) {
			echo '<div class="notice notice-success is-dismissible"><p>' . esc_html__( 'License activated — your plan is unlocked.', 'pressconduit' ) . '</p></div>';
		}
		if ( isset( $_GET['license_failed'] ) && class_exists( 'PCD_PC_License' ) ) {
			echo '<div class="notice notice-error is-dismissible"><p>' . esc_html__( 'License activation failed: ', 'pressconduit' ) . esc_html( PCD_PC_License::last_error() ) . '</p></div>';
		}
		if ( isset( $_GET['license_deactivated'] ) ) {
			echo '<div class="notice notice-info is-dismissible"><p>' . esc_html__( 'License deactivated on this site.', 'pressconduit' ) . '</p></div>';
		}
		// phpcs:enable
	}

	private static function render_tabs( string $active ): void {
		$tabs = [
			'connection' => __( 'Connection', 'pressconduit' ),
			'tools'      => __( 'Tools', 'pressconduit' ),
			'activity'   => __( 'Activity', 'pressconduit' ),
			'snapshots'  => __( 'Snapshots', 'pressconduit' ),
			'settings'   => __( 'Settings', 'pressconduit' ),
		];
		echo '<nav class="pcd-admin-tabs" aria-label="' . esc_attr__( 'PressConduit sections', 'pressconduit' ) . '">';
		foreach ( $tabs as $key => $label ) {
			$cls = $active === $key ? 'is-active' : '';
			$url = add_query_arg( [ 'page' => self::PAGE_SLUG, 'tab' => $key ], admin_url( 'admin.php' ) );
			printf( '<a class="%s" href="%s">%s</a>', esc_attr( $cls ), esc_url( $url ), esc_html( $label ) );
		}
		echo '</nav>';
	}

	// ------------------------------------------------------------------
	// Connection tab
	// ------------------------------------------------------------------

	private static function render_connection(): void {
		$paired = PCD_PC_Pair::is_paired();
		?>
		<section class="pcd-admin-card htd5-admin__panel">

			<div style="text-align:center;padding:24px 0 8px">
				<h2 style="margin:0 0 6px;font-size:22px"><?php esc_html_e( 'Your AI just learned WordPress.', 'pressconduit' ); ?></h2>
				<p style="margin:0 0 18px;color:#555;font-size:14px;max-width:520px;margin-left:auto;margin-right:auto">
					<?php esc_html_e( 'Connect this site to PressConduit to manage content, edit themes, and build pages with Claude, ChatGPT, or Cursor.', 'pressconduit' ); ?>
				</p>
				<form method="post" action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>" target="_blank" style="display:inline-block">
					<?php wp_nonce_field( 'pcd_pc_connect' ); ?>
					<input type="hidden" name="action" value="pcd_pc_connect" />
					<button type="submit" class="button button-primary button-hero">
						<?php esc_html_e( 'Connect to Conduit', 'pressconduit' ); ?>
					</button>
				</form>
				<p style="margin-top:10px;color:#777;font-size:12px">
					<?php esc_html_e( 'Opens a new tab where you can copy your MCP URL.', 'pressconduit' ); ?>
				</p>
			</div>

			<?php if ( $paired ) : ?>
				<div class="pcd-pc-connectors" style="margin-top:24px">
					<div class="pcd-pc-connector-card">
						<h4><span class="dashicons dashicons-format-chat" style="color:#cc785c"></span> <?php esc_html_e( 'Claude.com / Claude Desktop', 'pressconduit' ); ?></h4>
						<p class="description"><?php esc_html_e( 'Settings → Connectors → Add custom connector → paste the URL.', 'pressconduit' ); ?></p>
						<a class="button button-primary" href="https://claude.ai/settings/connectors" target="_blank" rel="noopener">
							<?php esc_html_e( 'Open Claude Connectors', 'pressconduit' ); ?>
						</a>
					</div>
					<div class="pcd-pc-connector-card">
						<h4><span class="dashicons dashicons-admin-comments" style="color:#10a37f"></span> <?php esc_html_e( 'ChatGPT', 'pressconduit' ); ?></h4>
						<p class="description"><?php esc_html_e( 'Settings → Connectors → Add → paste the URL.', 'pressconduit' ); ?></p>
						<a class="button button-primary" href="https://chatgpt.com/#settings/Connectors" target="_blank" rel="noopener">
							<?php esc_html_e( 'Open ChatGPT Connectors', 'pressconduit' ); ?>
						</a>
					</div>
				</div>

				<form method="post" action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>" style="margin-top:20px">
					<?php wp_nonce_field( 'pcd_pc_unpair' ); ?>
					<input type="hidden" name="action" value="pcd_pc_unpair" />
					<button type="submit" class="button button-secondary"><?php esc_html_e( 'Unpair (clears local state)', 'pressconduit' ); ?></button>
				</form>
			<?php endif; ?>
		</section>
		<?php
	}

	// ------------------------------------------------------------------
	// Settings tab — backend URL, linked user, token rotate
	// ------------------------------------------------------------------

	private static function render_settings(): void {
		$user_id = PCD_PC_Auth::get_linked_user_id();

		?>
		<?php if ( pcd_pc_is_direct_build() ) : ?>
		<section class="pcd-admin-card htd5-admin__panel pcd-pc-section">
			<h3 style="margin-top:0"><?php esc_html_e( 'License', 'pressconduit' ); ?></h3>
			<?php
			$lic_active = PCD_PC_License::is_active();
			$lic_plan   = PCD_PC_License::plan();
			$lic_key    = PCD_PC_License::key();
			$lic_err    = PCD_PC_License::last_error();
			?>
			<?php if ( $lic_active ) : ?>
				<p class="description" style="color:#1b9c7a;font-weight:600">
					<span class="dashicons dashicons-yes-alt"></span>
					<?php
					/* translators: %s: subscription plan name. */
					echo esc_html( sprintf( __( 'Active — %s plan.', 'pressconduit' ), ucfirst( $lic_plan ) ) ); ?>
				</p>
				<form method="post" action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>">
					<?php wp_nonce_field( 'pcd_pc_deactivate_license' ); ?>
					<input type="hidden" name="action" value="pcd_pc_deactivate_license" />
					<button type="submit" class="button button-secondary"><?php esc_html_e( 'Deactivate License', 'pressconduit' ); ?></button>
				</form>
			<?php else : ?>
				<p class="description"><?php esc_html_e( 'Paste the license key from your SureCart receipt to unlock your plan. (Connect this site on the Connection tab first.)', 'pressconduit' ); ?></p>
				<p class="description"><?php
				/* translators: %s: link to view plans. */
				printf( esc_html__( 'Don\'t have a key yet? %s.', 'pressconduit' ), '<a href="' . esc_url( PCD_PC_License::purchase_url() ) . '" target="_blank" rel="noopener">' . esc_html__( 'View plans and get one', 'pressconduit' ) . '</a>' ); ?></p>
				<?php if ( '' !== $lic_err ) : ?>
					<p class="description" style="color:#b32d2e"><?php echo esc_html( $lic_err ); ?></p>
				<?php endif; ?>
				<form method="post" action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>">
					<?php wp_nonce_field( 'pcd_pc_activate_license' ); ?>
					<input type="hidden" name="action" value="pcd_pc_activate_license" />
					<div class="pcd-pc-form-row">
						<input type="text" name="license_key" value="<?php echo esc_attr( $lic_key ); ?>" class="regular-text" placeholder="<?php esc_attr_e( 'License key', 'pressconduit' ); ?>" autocomplete="off" />
						<button type="submit" class="button button-primary"><?php esc_html_e( 'Activate', 'pressconduit' ); ?></button>
					</div>
				</form>
			<?php endif; ?>
		</section>
		<?php else : ?>
		<section class="pcd-admin-card htd5-admin__panel pcd-pc-section">
			<h3 style="margin-top:0"><?php esc_html_e( 'PressConduit Plans', 'pressconduit' ); ?></h3>
			<p class="description"><?php esc_html_e( 'Want unlimited sites and the full tool surface? View the plans on our website.', 'pressconduit' ); ?></p>
			<p><a href="https://pcdesignstx.com/pressconduit/" class="button button-primary" target="_blank" rel="noopener"><?php esc_html_e( 'View Plans', 'pressconduit' ); ?></a></p>
		</section>
		<?php endif; ?>

		<section class="pcd-admin-card htd5-admin__panel pcd-pc-section">
			<h3 style="margin-top:0"><?php esc_html_e( 'Linked WordPress User', 'pressconduit' ); ?></h3>
			<form method="post" action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>">
				<?php wp_nonce_field( 'pcd_pc_set_user' ); ?>
				<input type="hidden" name="action" value="pcd_pc_set_user" />
				<div class="pcd-pc-form-row">
					<?php wp_dropdown_users( [
						'name'     => 'user_id',
						'selected' => $user_id,
						'show'     => 'display_name_with_login',
						'role__in' => [ 'administrator', 'editor' ],
					] ); ?>
					<button type="submit" class="button"><?php esc_html_e( 'Save', 'pressconduit' ); ?></button>
				</div>
				<p class="description"><?php esc_html_e( 'AI tool calls run with this WordPress user\'s capabilities.', 'pressconduit' ); ?></p>
			</form>
		</section>

		<?php if ( pcd_pc_is_direct_build() ) : ?>
		<section class="pcd-admin-card htd5-admin__panel pcd-pc-section">
			<h3 style="margin-top:0"><?php esc_html_e( 'Updates', 'pressconduit' ); ?></h3>
			<p class="description">
				<?php
				$current = defined( 'PCD_PC_VERSION' ) ? PCD_PC_VERSION : '0.0.0';
				/* translators: %s: installed plugin version. */
				echo esc_html( sprintf( __( 'Installed version: %s', 'pressconduit' ), $current ) );
				?>
			</p>
			<p class="description"><?php esc_html_e( 'WordPress automatically checks every 12 hours. Hit this button to force an immediate check against the PC Designs release channel.', 'pressconduit' ); ?></p>
			<form method="post" action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>">
				<?php wp_nonce_field( 'pcd_pc_check_updates' ); ?>
				<input type="hidden" name="action" value="pcd_pc_check_updates" />
				<button type="submit" class="button button-primary"><?php esc_html_e( 'Check for Updates', 'pressconduit' ); ?></button>
			</form>
			<?php $auto_update = class_exists( 'PCD_PC_Updater' ) && PCD_PC_Updater::auto_update_enabled(); ?>
			<form method="post" action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>" style="margin-top:16px;border-top:1px solid #e2e4e7;padding-top:16px">
				<?php wp_nonce_field( 'pcd_pc_auto_update' ); ?>
				<input type="hidden" name="action" value="pcd_pc_auto_update" />
				<label class="pcd-pc-form-row" style="display:flex;align-items:center;gap:8px;margin-bottom:10px">
					<input type="checkbox" name="auto_update" value="1" <?php checked( $auto_update ); ?> />
					<?php esc_html_e( 'Install PressConduit updates automatically', 'pressconduit' ); ?>
				</label>
				<p class="description" style="margin-bottom:10px"><?php esc_html_e( 'Recommended. Some AI tools require a current build to work with the relay, so staying up to date keeps the connector reliable. Updates that need a newer WordPress or PHP version are never installed automatically.', 'pressconduit' ); ?></p>
				<button type="submit" class="button"><?php esc_html_e( 'Save', 'pressconduit' ); ?></button>
			</form>
		</section>
		<?php else : ?>
		<section class="pcd-admin-card htd5-admin__panel pcd-pc-section">
			<h3 style="margin-top:0"><?php esc_html_e( 'Updates', 'pressconduit' ); ?></h3>
			<p class="description">
				<?php
				$current = defined( 'PCD_PC_VERSION' ) ? PCD_PC_VERSION : '0.0.0';
				/* translators: %s: installed plugin version. */
				echo esc_html( sprintf( __( 'Installed version: %s', 'pressconduit' ), $current ) );
				?>
			</p>
			<?php if ( pcd_pc_is_wporg_build() ) : ?>
			<p class="description"><?php esc_html_e( 'Updates are delivered through WordPress.org.', 'pressconduit' ); ?></p>
			<?php else : ?>
			<p class="description"><?php esc_html_e( 'Updates are delivered through the Divi Marketplace.', 'pressconduit' ); ?></p>
			<?php endif; ?>
		</section>
		<?php endif; ?>

		<section class="pcd-admin-card htd5-admin__panel pcd-pc-section">
			<h3 style="margin-top:0"><?php esc_html_e( 'File Management', 'pressconduit' ); ?></h3>
			<?php $allow_files = (bool) get_option( 'pcd_pc_allow_file_tools' ); ?>
			<p class="description">
				<?php esc_html_e( 'Lets the AI file tools (read, list, edit, write) operate on theme, plugin, and mu-plugin files. Off by default. Writes are confined to wp-content/themes, plugins, and mu-plugins, and PHP edits are syntax-checked before they save.', 'pressconduit' ); ?>
			</p>
			<?php if ( defined( 'DISALLOW_FILE_EDIT' ) && DISALLOW_FILE_EDIT ) : ?>
				<p class="description" style="color:#b26b00">
					<?php esc_html_e( 'This site has DISALLOW_FILE_EDIT set in wp-config.php, which removes the edit_themes capability from everyone — that is why file tools are currently blocked. Turning this on lets PressConduit manage files anyway, running as the linked administrator. Leave it off if you intend file editing to stay locked down.', 'pressconduit' ); ?>
				</p>
			<?php endif; ?>
			<form method="post" action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>">
				<?php wp_nonce_field( 'pcd_pc_file_access' ); ?>
				<input type="hidden" name="action" value="pcd_pc_file_access" />
				<label class="pcd-pc-form-row" style="display:flex;align-items:center;gap:8px;margin-bottom:10px">
					<input type="checkbox" name="allow_file_tools" value="1" <?php checked( $allow_files ); ?> />
					<?php esc_html_e( 'Allow file management', 'pressconduit' ); ?>
				</label>
				<button type="submit" class="button"><?php esc_html_e( 'Save', 'pressconduit' ); ?></button>
			</form>
		</section>

		<section class="pcd-admin-card htd5-admin__panel pcd-pc-section">
			<h3 style="margin-top:0"><?php esc_html_e( 'Security', 'pressconduit' ); ?></h3>
			<p class="description"><?php esc_html_e( 'Rotate the secret the relay uses to communicate with this site. Existing pairing will be invalidated — re-pair on the Connection tab after rotating.', 'pressconduit' ); ?></p>
			<form method="post" action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>">
				<?php wp_nonce_field( 'pcd_pc_rotate_token' ); ?>
				<input type="hidden" name="action" value="pcd_pc_rotate_token" />
				<button type="submit" class="button button-secondary"><?php esc_html_e( 'Rotate Site Secret', 'pressconduit' ); ?></button>
			</form>
		</section>
		<?php
	}

	// ------------------------------------------------------------------
	// Tools / Activity / Snapshots tabs
	// ------------------------------------------------------------------

	private static function render_tools(): void {
		$tools = PCD_PC_Tools::list_for_mcp();
		echo '<section class="pcd-admin-card htd5-admin__panel">';
		/* translators: %d: number of registered tools. */
		echo '<h3 style="margin-top:0">' . esc_html( sprintf( __( '%d Tools Registered', 'pressconduit' ), count( $tools ) ) ) . '</h3>';
		echo '<table class="pcd-pc-table"><thead><tr><th>Name</th><th>Description</th></tr></thead><tbody>';
		foreach ( $tools as $t ) {
			printf( '<tr><td><code>%s</code></td><td>%s</td></tr>', esc_html( $t['name'] ), esc_html( $t['description'] ) );
		}
		echo '</tbody></table></section>';
	}

	private static function render_activity(): void {
		$rows = PCD_PC_Audit::recent( 100 );
		echo '<section class="pcd-admin-card htd5-admin__panel">';
		echo '<h3 style="margin-top:0">' . esc_html__( 'Recent Tool Calls', 'pressconduit' ) . '</h3>';
		if ( ! $rows ) {
			echo '<div class="pcd-pc-empty">' . esc_html__( 'No activity yet. Pair the site and connect an AI client to start using tools.', 'pressconduit' ) . '</div></section>';
			return;
		}
		echo '<table class="pcd-pc-table"><thead><tr><th>When</th><th>Tool</th><th>Status</th><th>Time</th></tr></thead><tbody>';
		foreach ( $rows as $r ) {
			printf(
				'<tr><td>%s</td><td><code>%s</code></td><td>%s</td><td>%dms</td></tr>',
				esc_html( $r['created_at'] ),
				esc_html( $r['tool'] ),
				esc_html( $r['result_status'] ),
				(int) $r['elapsed_ms']
			);
		}
		echo '</tbody></table></section>';
	}

	private static function render_snapshots(): void {
		$rows = PCD_PC_Snapshot::recent( 100 );
		echo '<section class="pcd-admin-card htd5-admin__panel">';
		echo '<h3 style="margin-top:0">' . esc_html__( 'Snapshots (Undo)', 'pressconduit' ) . '</h3>';
		if ( ! $rows ) {
			echo '<div class="pcd-pc-empty">' . esc_html__( 'No snapshots yet. Tool calls that mutate state will record snapshots here.', 'pressconduit' ) . '</div></section>';
			return;
		}
		echo '<table class="pcd-pc-table"><thead><tr><th>When</th><th>Kind</th><th>Ref</th><th>Label</th><th>Action</th></tr></thead><tbody>';
		foreach ( $rows as $r ) {
			$nonce = wp_create_nonce( 'pcd_pc_restore' );
			$form  = sprintf(
				'<form method="post" action="%s" style="display:inline"><input type="hidden" name="action" value="pcd_pc_restore"/><input type="hidden" name="_wpnonce" value="%s"/><input type="hidden" name="snapshot_id" value="%d"/><button class="button button-small">Restore</button></form>',
				esc_url( admin_url( 'admin-post.php' ) ),
				esc_attr( $nonce ),
				(int) $r['id']
			);
			printf(
				'<tr><td>%s</td><td>%s</td><td><code>%s</code></td><td>%s</td><td>%s</td></tr>',
				esc_html( $r['created_at'] ),
				esc_html( $r['kind'] ),
				esc_html( $r['ref_key'] ),
				esc_html( (string) $r['label'] ),
				$form // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
			);
		}
		echo '</tbody></table></section>';
	}
}
