<?php

namespace WPD_Platform;

use Dollie\SDK\Controllers\IntegrationsController;
use WPD_Platform\Services\ChqApiClient;

/**
 * Class Admin
 *
 * Handles administrative functionality for the platform including settings pages,
 * site connection management, and update triggers.
 *
 * @package WPD_Platform
 * @since 1.0.0
 */
class Admin extends Singleton {

	/**
	 * Add the settings page to WordPress admin.
	 *
	 * @since 1.0.0
	 * @return void
	 */
	public function settings_page() {
		// Show just for externally hosted.
		if ( ! Plugin::instance()->get_host()->is_type_external() ) {
			return;
		}

		$hook_suffix = add_options_page(
			'Dollie Connect',
			'Dollie Connect',
			'manage_options',
			'dollie-connect',
			[ $this, 'settings_page_content' ]
		);
		add_action( "load-{$hook_suffix}", [ $this, 'enqueue_assets' ] );
	}

	/**
	 * Enqueue admin page assets — only loads on plugin pages.
	 *
	 * @since 1.0.0
	 * @return void
	 */
	public function enqueue_assets() {
		wp_enqueue_style( 'dollie-admin', PLATFORM_PLUGIN_URL . 'assets/dst/admin.css', [], PLATFORM_VERSION );
		wp_enqueue_script( 'alpine', PLATFORM_PLUGIN_URL . 'assets/js/alpine.min.js', [], PLATFORM_VERSION, true );
		wp_enqueue_script( 'dollie-sweetalert', PLATFORM_PLUGIN_URL . 'assets/js/sweetalert.min.js', [], PLATFORM_VERSION, true );
		wp_enqueue_style( 'dollie-sweetalert-style', PLATFORM_PLUGIN_URL . 'assets/css/sweetalert.css', [], PLATFORM_VERSION );
	}

	/**
	 * Handle AJAX request to remove site connection.
	 *
	 * @since 1.0.0
	 * @return void
	 */
	public function ajax_callback_remove_site() {
		// Check for nonce security.
		if ( ! wp_verify_nonce( $_POST['nonce'], 'dollie_connect_ajax_nonce' ) ) {
			wp_send_json_error( __( 'You do not have permission to perform this action.', 'dollie' ) );
		}

		if ( ! current_user_can( 'manage_options' ) ) {
			wp_send_json_error( __( 'You do not have permission to perform this action.', 'dollie' ) );
		}

		if ( ! get_option( 'wpd_connection_id' ) ) {
			wp_send_json_error( __( 'This site is not connected to Dollie.', 'dollie' ) );
		}

		$signature = sha1( Plugin::instance()->get_host()->get_token() . Plugin::instance()->get_host()->get_partner_hash() );

		$api_host = defined( 'WPD_WORKER_API_URL' ) ? WPD_WORKER_API_URL : Utils\HostInterface::API_URL;

		$response = wp_remote_request(
			$api_host . 'external-sites/' . get_option( 'wpd_connection_id' ),
			array(
				'method'  => 'DELETE',
				'headers' => array(
					'Authorization' => $signature,
				),

				'timeout' => 30,
			)
		);

		if ( ! is_wp_error( $response ) ) {
			$data = wp_remote_retrieve_body( $response );
			$data = @json_decode( $data );

			if ( isset( $data->message ) ) {
				Plugin::instance()->get_host()->remove_connection();
				wp_send_json_success( $data->message );
			}
			wp_send_json_error( json_encode( $response ) );
		}

		wp_send_json_error( __( 'Something went wrong while disconnecting. Please try again.', 'dollie' ) );
		wp_die();
	}

	/**
	 * Handle AJAX request to connect site.
	 *
	 * @since 1.0.0
	 * @return void
	 */
	public function ajax_callback_connect_site() {
		// Check for nonce security.
		if ( ! wp_verify_nonce( $_POST['nonce'], 'dollie_connect_ajax_nonce' ) ) {
			wp_send_json_error( __( 'You do not have permission to perform this action.', 'dollie' ) );
		}

		if ( ! current_user_can( 'manage_options' ) ) {
			wp_send_json_error( __( 'You do not have permission to perform this action.', 'dollie' ) );
		}

		$registered = Plugin::instance()->get_host()->register_site();

		if ( $registered ) {
			wp_send_json_success(
				[
					'site'  => $registered,
					'data'  => __( 'Your site has been connected to Dollie.', 'dollie' ),
					'token' => Plugin::instance()->get_host()->get_token(),
				]
			);
		}

		wp_send_json_error( __( 'Something went wrong while connecting. Please try again.', 'dollie' ) );
		wp_die();
	}

	/**
	 * Render the settings page content.
	 *
	 * @since 1.0.0
	 * @return void
	 */
	public function settings_page_content() {
		$wpd_token        = get_option( 'wpd_token' );
		$site_hash        = get_option( 'wpd_connection_id' );
		$has_partner_hash = (bool) Plugin::instance()->get_host()->get_partner_hash();

		// Gather detected integrations for the connected state.
		$all_integrations = IntegrationsController::get_integrations();
		$active_integrations = [];

		foreach ( $all_integrations as $id => $integration ) {
			if ( $integration->is_plugin_installed() ) {
				$active_integrations[ $id ] = $integration;
			}
		}

		uasort( $active_integrations, fn( $a, $b ) => strcasecmp( $a->get_name(), $b->get_name() ) );

		$all_triggers = apply_filters( 'dollie_trigger_register_trigger', [] );
		$all_actions  = apply_filters( 'dollie_trigger_register_action', [] );

		// Gather WordPress Abilities (from the WP Abilities API / MCP Adapter).
		$wp_abilities = [];
		if ( function_exists( 'wp_get_abilities' ) ) {
			foreach ( wp_get_abilities() as $ability ) {
				$meta       = $ability->get_meta();
				$is_public  = $meta['mcp']['public'] ?? false;
				$mcp_type   = $meta['mcp']['type'] ?? 'tool';

				if ( ! $is_public || 'tool' !== $mcp_type ) {
					continue;
				}

				$category = $ability->get_category() ?: 'uncategorized';
				$wp_abilities[ $category ][] = [
					'name'        => $ability->get_name(),
					'label'       => $ability->get_label(),
					'description' => $ability->get_description(),
				];
			}
			ksort( $wp_abilities );
		}
		$image_url        = Whitelabel::instance()->get_text( 'connect_img_url' ) === 'connect_img_url'
			? esc_url( PLATFORM_PLUGIN_URL . 'assets/icons/icon-128x128.png' )
			: esc_url( Whitelabel::instance()->get_text( 'connect_img_url' ) );

		// Build the CHQ connect URL for wordpress.org installs (no partner_hash).
		$connect_url = '';
		if ( ! $has_partner_hash ) {
			$chq_base_url = defined( 'WPD_WORKER_API_URL' )
				? preg_replace( '#/api/?$#', '/', WPD_WORKER_API_URL )
				: Utils\HostInterface::API_BASE_URL;

			// Generate a state param for CSRF protection on the redirect callback.
			$state = wp_generate_password( 32, false );
			set_transient( 'wpd_connection_state', $state, DAY_IN_SECONDS );

			$connect_url = $chq_base_url . 'connect/site/start?' . http_build_query( [
				'site_url'      => site_url(),
				'plugin_active' => '1',
				'state'         => $state,
			] );
		}
		?>
		<div class="dollie-admin">
		<div x-data="{
				isLoading: false,
				isSuccess: false,
				isError: false,
				message: '',
				token: '<?php echo esc_attr( $wpd_token ); ?>',
				site: '<?php echo esc_attr( $site_hash ); ?>'
				}" class="max-w-7xl mx-auto mt-6 px-4 sm:px-6 lg:px-8">

			<div class="bg-white shadow-sm rounded-xl overflow-hidden border border-zinc-200">
				<!-- Header -->
				<div class="px-6 py-6 flex items-center gap-4 border-b border-zinc-100">
					<img src="<?php echo esc_url( $image_url ); ?>"
						 alt="<?php esc_attr_e( 'Dollie', 'dollie' ); ?>"
						 class="h-12 w-12 rounded-lg">
					<div>
						<h2 class="text-lg font-semibold text-zinc-900">
							<?php echo esc_html( Whitelabel::instance()->get_text( 'Dollie AI - Connect' ) ); ?>
						</h2>
						<p class="text-sm text-zinc-500">
							<?php esc_html_e( 'Your Agency HQ for the AI Era', 'dollie' ); ?>
						</p>
					</div>
				</div>

				<!-- Connected State -->
				<div x-show="token && site" class="px-6 py-5">
					<div class="flex items-center gap-2 mb-5">
						<span class="inline-flex h-2 w-2 rounded-full bg-emerald-500"></span>
						<span class="text-sm font-medium text-emerald-600"><?php esc_html_e( 'Connected', 'dollie' ); ?></span>
					</div>

					<div class="space-y-4">
						<div>
							<label class="block text-sm font-medium text-zinc-500 mb-1">
								<?php esc_html_e( 'Auth Token', 'dollie' ); ?>
							</label>
							<input type="text" x-model="token" disabled
								   class="bg-zinc-50 border border-zinc-200 text-zinc-600 rounded-lg py-2 px-3 w-full text-sm font-mono">
						</div>

						<div class="pt-2">
							<button
								class="bg-red-600 hover:bg-red-500 text-white text-sm font-medium py-2 px-4 rounded-lg transition-colors disabled:opacity-50"
								x-bind="RemoveButton"
								x-html="isLoading ? `<span class='dashicons dashicons-update spin'></span> <?php esc_html_e( 'Disconnecting...', 'dollie' ); ?>` : '<?php esc_html_e( 'Disconnect Site', 'dollie' ); ?>'"
							>
								<?php esc_html_e( 'Disconnect Site', 'dollie' ); ?>
							</button>
						</div>
					</div>
				</div>

				<!-- Not Connected State -->
				<div x-show="!token || !site" class="px-6 py-6">
					<p class="text-sm text-zinc-600 mb-4">
						<?php esc_html_e( 'Connect this site to your Dollie workspace. Once connected, you can manage it through AI conversations, MCP tools, or the Dollie dashboard.', 'dollie' ); ?>
					</p>

					<button
						class="bg-zinc-900 hover:bg-zinc-800 text-white text-sm font-medium py-2.5 px-5 rounded-lg transition-colors disabled:opacity-50"
						x-bind="ConnectButton"
						x-html="isLoading ? `<span class='dashicons dashicons-update spin'></span> <?php esc_html_e( 'Connecting...', 'dollie' ); ?>` : '<?php esc_html_e( 'Connect Site', 'dollie' ); ?>'"
					>
						<?php esc_html_e( 'Connect Site', 'dollie' ); ?>
					</button>
				</div>
			</div>

			<!-- Message Banner -->
			<div x-show="message"
				 x-transition
				 :class="isSuccess ? 'bg-emerald-50 border-emerald-200 text-emerald-700' : 'bg-red-50 border-red-200 text-red-700'"
				 class="border text-sm font-medium mt-4 p-3 rounded-lg"
				 x-html="message"></div>

			<!-- Resource Cards (shown when connected) -->
			<div x-show="token && site" class="mt-6">
				<p class="text-xs font-medium uppercase tracking-wider text-zinc-400 mb-3 px-1">
					<?php esc_html_e( 'Resources', 'dollie' ); ?>
				</p>
				<div class="grid grid-cols-2 gap-3">
					<a href="https://app.dollie.pro/docs/getting-started" target="_blank" rel="noopener noreferrer"
					   class="group bg-white rounded-xl border border-zinc-200 p-5 text-center shadow-sm transition-all hover:shadow-md hover:border-zinc-300">
						<div class="mx-auto mb-3 flex h-10 w-10 items-center justify-center rounded-lg bg-zinc-100 transition-colors group-hover:bg-zinc-900">
							<svg class="h-5 w-5 text-zinc-500 transition-colors group-hover:text-white" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
								<path stroke-linecap="round" stroke-linejoin="round" d="M12 6.042A8.967 8.967 0 006 3.75c-1.052 0-2.062.18-3 .512v14.25A8.987 8.987 0 016 18c2.305 0 4.408.867 6 2.292m0-14.25a8.966 8.966 0 016-2.292c1.052 0 2.062.18 3 .512v14.25A8.987 8.987 0 0018 18a8.967 8.967 0 00-6 2.292m0-14.25v14.25" />
							</svg>
						</div>
						<span class="block text-sm font-medium text-zinc-900"><?php esc_html_e( 'Docs', 'dollie' ); ?></span>
						<span class="block text-xs text-zinc-400 mt-0.5"><?php esc_html_e( 'Getting started', 'dollie' ); ?></span>
					</a>

					<a href="https://app.dollie.pro/docs/developers/overview" target="_blank" rel="noopener noreferrer"
					   class="group bg-white rounded-xl border border-zinc-200 p-5 text-center shadow-sm transition-all hover:shadow-md hover:border-zinc-300">
						<div class="mx-auto mb-3 flex h-10 w-10 items-center justify-center rounded-lg bg-zinc-100 transition-colors group-hover:bg-zinc-900">
							<svg class="h-5 w-5 text-zinc-500 transition-colors group-hover:text-white" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
								<path stroke-linecap="round" stroke-linejoin="round" d="M17.25 6.75L22.5 12l-5.25 5.25m-10.5 0L1.5 12l5.25-5.25m7.5-3l-4.5 16.5" />
							</svg>
						</div>
						<span class="block text-sm font-medium text-zinc-900"><?php esc_html_e( 'Developer SDK', 'dollie' ); ?></span>
						<span class="block text-xs text-zinc-400 mt-0.5"><?php esc_html_e( 'Build integrations', 'dollie' ); ?></span>
					</a>

					<a href="https://app.dollie.pro/docs/chrome-extension" target="_blank" rel="noopener noreferrer"
					   class="group bg-white rounded-xl border border-zinc-200 p-5 text-center shadow-sm transition-all hover:shadow-md hover:border-zinc-300">
						<div class="mx-auto mb-3 flex h-10 w-10 items-center justify-center rounded-lg bg-zinc-100 transition-colors group-hover:bg-zinc-900">
							<svg class="h-5 w-5 text-zinc-500 transition-colors group-hover:text-white" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
								<path stroke-linecap="round" stroke-linejoin="round" d="M12 21a9.004 9.004 0 008.716-6.747M12 21a9.004 9.004 0 01-8.716-6.747M12 21c2.485 0 4.5-4.03 4.5-9S14.485 3 12 3m0 18c-2.485 0-4.5-4.03-4.5-9S9.515 3 12 3m0 0a8.997 8.997 0 017.843 4.582M12 3a8.997 8.997 0 00-7.843 4.582m15.686 0A11.953 11.953 0 0112 10.5c-2.998 0-5.74-1.1-7.843-2.918m15.686 0A8.959 8.959 0 0121 12c0 .778-.099 1.533-.284 2.253m0 0A17.919 17.919 0 0112 16.5a17.92 17.92 0 01-8.716-2.247m0 0A8.966 8.966 0 013 12c0-1.264.26-2.467.732-3.558" />
							</svg>
						</div>
						<span class="block text-sm font-medium text-zinc-900"><?php esc_html_e( 'Chrome Extension', 'dollie' ); ?></span>
						<span class="block text-xs text-zinc-400 mt-0.5"><?php esc_html_e( 'AI in your browser', 'dollie' ); ?></span>
					</a>

					<a href="https://app.dollie.pro/docs/desktop-app" target="_blank" rel="noopener noreferrer"
					   class="group bg-white rounded-xl border border-zinc-200 p-5 text-center shadow-sm transition-all hover:shadow-md hover:border-zinc-300">
						<div class="mx-auto mb-3 flex h-10 w-10 items-center justify-center rounded-lg bg-zinc-100 transition-colors group-hover:bg-zinc-900">
							<svg class="h-5 w-5 text-zinc-500 transition-colors group-hover:text-white" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
								<path stroke-linecap="round" stroke-linejoin="round" d="M9 17.25v1.007a3 3 0 01-.879 2.122L7.5 21h9l-.621-.621A3 3 0 0115 18.257V17.25m6-12V15a2.25 2.25 0 01-2.25 2.25H5.25A2.25 2.25 0 013 15V5.25m18 0A2.25 2.25 0 0018.75 3H5.25A2.25 2.25 0 003 5.25m18 0V12a2.25 2.25 0 01-2.25 2.25H5.25A2.25 2.25 0 013 12V5.25" />
							</svg>
						</div>
						<span class="block text-sm font-medium text-zinc-900"><?php esc_html_e( 'Desktop App', 'dollie' ); ?></span>
						<span class="block text-xs text-zinc-400 mt-0.5"><?php esc_html_e( 'Native experience', 'dollie' ); ?></span>
					</a>
				</div>
			</div>

			<!-- Detected Integrations (shown when connected) -->
			<?php if ( ! empty( $active_integrations ) ) : ?>
			<div x-show="token && site" class="mt-6">
				<p class="text-xs font-medium uppercase tracking-wider text-zinc-400 mb-3 px-1">
					<?php esc_html_e( 'Detected Integrations', 'dollie' ); ?>
				</p>

				<div class="space-y-2">
					<?php foreach ( $active_integrations as $id => $integration ) :
						$triggers      = isset( $all_triggers[ $id ] ) ? $all_triggers[ $id ] : [];
						$actions       = isset( $all_actions[ $id ] ) ? $all_actions[ $id ] : [];
						$trigger_count = count( $triggers );
						$action_count  = count( $actions );
						$has_triggers  = $trigger_count > 0;
						$has_actions   = $action_count > 0;
						$default_tab   = $has_triggers ? 'triggers' : 'actions';
					?>
					<div x-data="{ open: false, tab: '<?php echo esc_attr( $default_tab ); ?>' }"
						 class="bg-white rounded-xl border border-zinc-200 shadow-sm overflow-hidden transition-shadow"
						 :class="open && 'shadow-md ring-1 ring-zinc-200'">

						<!-- Accordion Header -->
						<button @click="open = !open"
								class="w-full px-5 py-4 flex items-center gap-4 text-left transition-colors hover:bg-zinc-50">
							<!-- Integration icon -->
							<span class="flex-shrink-0 flex items-center justify-center h-9 w-9 rounded-lg bg-zinc-100">
								<svg class="h-4 w-4 text-zinc-500" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
									<path stroke-linecap="round" stroke-linejoin="round" d="M14.25 6.087c0-.355.186-.676.401-.959.221-.29.349-.634.349-1.003 0-1.036-1.007-1.875-2.25-1.875s-2.25.84-2.25 1.875c0 .369.128.713.349 1.003.215.283.401.604.401.959v0a.64.64 0 01-.657.643 48.39 48.39 0 01-4.163-.3c.186 1.613.293 3.25.315 4.907a.656.656 0 01-.658.663v0c-.355 0-.676-.186-.959-.401a1.647 1.647 0 00-1.003-.349c-1.036 0-1.875 1.007-1.875 2.25s.84 2.25 1.875 2.25c.369 0 .713-.128 1.003-.349.283-.215.604-.401.959-.401v0c.31 0 .555.26.532.57a48.039 48.039 0 01-.642 5.056c1.518.19 3.058.309 4.616.354a.64.64 0 00.657-.643v0c0-.355-.186-.676-.401-.959a1.647 1.647 0 01-.349-1.003c0-1.035 1.008-1.875 2.25-1.875 1.243 0 2.25.84 2.25 1.875 0 .369-.128.713-.349 1.003-.215.283-.401.604-.401.959v0c0 .333.277.607.61.654a48.24 48.24 0 005.427.058 48.394 48.394 0 00.06-4.998.636.636 0 00-.66-.61v0c-.354 0-.675.186-.958.401a1.647 1.647 0 01-1.003.349c-1.035 0-1.875-1.007-1.875-2.25s.84-2.25 1.875-2.25c.369 0 .713.128 1.003.349.283.215.604.401.959.401v0a.656.656 0 00.658-.663 48.422 48.422 0 00-.37-5.36c-1.886.342-3.81.574-5.766.689a.578.578 0 01-.61-.58v0z" />
								</svg>
							</span>

							<!-- Name & counts -->
							<div class="flex-1 min-w-0">
								<span class="text-sm font-medium text-zinc-900"><?php echo esc_html( $integration->get_name() ); ?></span>
								<div class="flex items-center gap-3 mt-0.5">
									<?php if ( $has_triggers ) : ?>
									<span class="text-xs text-zinc-400"><?php echo esc_html( $trigger_count ); ?> <?php echo esc_html( _n( 'trigger', 'triggers', $trigger_count, 'dollie' ) ); ?></span>
									<?php endif; ?>
									<?php if ( $has_triggers && $has_actions ) : ?>
									<span class="text-zinc-300">&middot;</span>
									<?php endif; ?>
									<?php if ( $has_actions ) : ?>
									<span class="text-xs text-zinc-400"><?php echo esc_html( $action_count ); ?> <?php echo esc_html( _n( 'action', 'actions', $action_count, 'dollie' ) ); ?></span>
									<?php endif; ?>
								</div>
							</div>

							<!-- Chevron -->
							<svg :class="open && 'rotate-180'"
								 class="flex-shrink-0 h-4 w-4 text-zinc-400 transition-transform duration-200"
								 fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
								<path stroke-linecap="round" stroke-linejoin="round" d="M19 9l-7 7-7-7"></path>
							</svg>
						</button>

						<!-- Accordion Body -->
						<div x-show="open" x-collapse>
							<?php if ( $has_triggers || $has_actions ) : ?>
							<div class="border-t border-zinc-100">
								<!-- Tabs -->
								<?php if ( $has_triggers && $has_actions ) : ?>
								<div class="flex border-b border-zinc-100">
									<button @click="tab = 'triggers'"
											:class="tab === 'triggers' ? 'text-zinc-900 border-zinc-900' : 'text-zinc-400 border-transparent hover:text-zinc-600'"
											class="flex-1 text-xs font-medium py-2.5 text-center border-b-2 transition-colors">
										<?php esc_html_e( 'Triggers', 'dollie' ); ?>
										<span class="ml-1 text-zinc-300" x-text="'(<?php echo esc_attr( $trigger_count ); ?>)'"></span>
									</button>
									<button @click="tab = 'actions'"
											:class="tab === 'actions' ? 'text-zinc-900 border-zinc-900' : 'text-zinc-400 border-transparent hover:text-zinc-600'"
											class="flex-1 text-xs font-medium py-2.5 text-center border-b-2 transition-colors">
										<?php esc_html_e( 'Actions', 'dollie' ); ?>
										<span class="ml-1 text-zinc-300" x-text="'(<?php echo esc_attr( $action_count ); ?>)'"></span>
									</button>
								</div>
								<?php endif; ?>

								<!-- Triggers List -->
								<?php if ( $has_triggers ) : ?>
								<div x-show="tab === 'triggers'" class="px-5 py-3">
									<ul class="space-y-1">
										<?php foreach ( $triggers as $trigger ) : ?>
										<li class="flex items-start gap-2 py-1">
											<svg class="flex-shrink-0 h-3.5 w-3.5 text-emerald-500 mt-0.5" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
												<path stroke-linecap="round" stroke-linejoin="round" d="M13 10V3L4 14h7v7l9-11h-7z" />
											</svg>
											<span class="text-sm text-zinc-600 leading-snug"><?php echo esc_html( $trigger['label'] ); ?></span>
										</li>
										<?php endforeach; ?>
									</ul>
								</div>
								<?php endif; ?>

								<!-- Actions List -->
								<?php if ( $has_actions ) : ?>
								<div x-show="tab === 'actions'" class="px-5 py-3">
									<ul class="space-y-1">
										<?php foreach ( $actions as $action ) : ?>
										<li class="flex items-start gap-2 py-1">
											<svg class="flex-shrink-0 h-3.5 w-3.5 text-blue-500 mt-0.5" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
												<path stroke-linecap="round" stroke-linejoin="round" d="M5.636 5.636a9 9 0 1012.728 0M12 3v9" />
											</svg>
											<span class="text-sm text-zinc-600 leading-snug"><?php echo esc_html( $action['label'] ); ?></span>
										</li>
										<?php endforeach; ?>
									</ul>
								</div>
								<?php endif; ?>
							</div>
							<?php else : ?>
							<div class="border-t border-zinc-100 px-5 py-4">
								<p class="text-sm text-zinc-400 text-center"><?php esc_html_e( 'No triggers or actions registered.', 'dollie' ); ?></p>
							</div>
							<?php endif; ?>
						</div>
					</div>
					<?php endforeach; ?>
				</div>
			</div>
			<?php endif; ?>

			<!-- Discovered Abilities (from WP Abilities API) -->
			<?php if ( ! empty( $wp_abilities ) ) : ?>
			<div x-show="token && site" class="mt-6">
				<p class="text-xs font-medium uppercase tracking-wider text-zinc-400 mb-3 px-1">
					<?php esc_html_e( 'Discovered Abilities', 'dollie' ); ?>
					<span class="text-zinc-300 normal-case">&mdash; <?php echo esc_html( array_sum( array_map( 'count', $wp_abilities ) ) ); ?> <?php esc_html_e( 'available via AI', 'dollie' ); ?></span>
				</p>

				<div class="space-y-2">
					<?php foreach ( $wp_abilities as $category => $abilities ) : ?>
					<div x-data="{ open: false }"
						 class="bg-white rounded-xl border border-zinc-200 shadow-sm overflow-hidden transition-shadow"
						 :class="open && 'shadow-md ring-1 ring-zinc-200'">

						<button @click="open = !open"
								class="w-full px-5 py-4 flex items-center gap-4 text-left transition-colors hover:bg-zinc-50">
							<span class="flex-shrink-0 flex items-center justify-center h-9 w-9 rounded-lg bg-violet-50">
								<svg class="h-4 w-4 text-violet-500" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
									<path stroke-linecap="round" stroke-linejoin="round" d="M9.813 15.904L9 18.75l-.813-2.846a4.5 4.5 0 00-3.09-3.09L2.25 12l2.846-.813a4.5 4.5 0 003.09-3.09L9 5.25l.813 2.846a4.5 4.5 0 003.09 3.09L15.75 12l-2.846.813a4.5 4.5 0 00-3.09 3.09zM18.259 8.715L18 9.75l-.259-1.035a3.375 3.375 0 00-2.455-2.456L14.25 6l1.036-.259a3.375 3.375 0 002.455-2.456L18 2.25l.259 1.035a3.375 3.375 0 002.455 2.456L21.75 6l-1.036.259a3.375 3.375 0 00-2.455 2.456z" />
								</svg>
							</span>

							<div class="flex-1 min-w-0">
								<span class="text-sm font-medium text-zinc-900"><?php echo esc_html( ucfirst( str_replace( [ '-', '_' ], ' ', $category ) ) ); ?></span>
								<div class="flex items-center gap-3 mt-0.5">
									<span class="text-xs text-zinc-400"><?php echo esc_html( count( $abilities ) ); ?> <?php echo esc_html( _n( 'ability', 'abilities', count( $abilities ), 'dollie' ) ); ?></span>
								</div>
							</div>

							<svg :class="open && 'rotate-180'"
								 class="flex-shrink-0 h-4 w-4 text-zinc-400 transition-transform duration-200"
								 fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
								<path stroke-linecap="round" stroke-linejoin="round" d="M19 9l-7 7-7-7"></path>
							</svg>
						</button>

						<div x-show="open" x-collapse>
							<div class="border-t border-zinc-100 px-5 py-3">
								<ul class="space-y-1">
									<?php foreach ( $abilities as $ability ) : ?>
									<li class="flex items-start gap-2 py-1">
										<svg class="flex-shrink-0 h-3.5 w-3.5 text-violet-400 mt-0.5" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
											<path stroke-linecap="round" stroke-linejoin="round" d="M9.813 15.904L9 18.75l-.813-2.846a4.5 4.5 0 00-3.09-3.09L2.25 12l2.846-.813a4.5 4.5 0 003.09-3.09L9 5.25l.813 2.846a4.5 4.5 0 003.09 3.09L15.75 12l-2.846.813a4.5 4.5 0 00-3.09 3.09z" />
										</svg>
										<div class="min-w-0">
											<span class="text-sm text-zinc-600 leading-snug"><?php echo esc_html( $ability['label'] ); ?></span>
											<?php if ( ! empty( $ability['description'] ) ) : ?>
											<p class="text-xs text-zinc-400 mt-0.5"><?php echo esc_html( $ability['description'] ); ?></p>
											<?php endif; ?>
										</div>
									</li>
									<?php endforeach; ?>
								</ul>
							</div>
						</div>
					</div>
					<?php endforeach; ?>
				</div>
			</div>
			<?php endif; ?>
		</div>
		<script>
		  document.addEventListener('alpine:init', () => {
			Alpine.bind('RemoveButton', () => ({
			  type: 'button',

			  '@click'() {
				this.isLoading = true;
				fetch('<?php echo admin_url( 'admin-ajax.php' ); ?>', {
				  method: 'POST',
				  headers: {
					'X-Requested-With': 'XMLHttpRequest'
				  },
				  body: new URLSearchParams({
					'action': 'dollie_connect_remove_site',
					'nonce': '<?php echo wp_create_nonce( 'dollie_connect_ajax_nonce' ); ?>'
				  })
				})
				  .then(response => response.json())
				  .then(json => {
					if (json.success) {
					  this.message = json.data;
					  this.token = '';
					  this.isSuccess = true;
					} else {
					  // Handle error response
					  this.message = json.data ?? 'An error occurred. Please try again!';
					}
					this.isLoading = false;
				  })
				  .catch(error => {
					// Handle fetch error
					this.isLoading = false;
					this.message = 'An error occurred. Please try again!';
				  });
			  },

			  ':disabled'() {
				return this.isLoading
			  },
			}));
			Alpine.bind('ConnectButton', () => ({
			  type: 'button',

			  '@click'() {
				<?php if ( ! $has_partner_hash ) : ?>
				// WordPress.org install: redirect to CHQ for plugin-active connection flow.
				this.isLoading = true;
				window.location.href = <?php echo wp_json_encode( $connect_url ); ?>;
				<?php else : ?>
				// Custom ZIP install: AJAX connect via partner_hash.
				this.isLoading = true;
				fetch('<?php echo admin_url( 'admin-ajax.php' ); ?>', {
				  method: 'POST',
				  headers: {
					'X-Requested-With': 'XMLHttpRequest'
				  },
				  body: new URLSearchParams({
					'action': 'dollie_connect_site',
					'nonce': '<?php echo wp_create_nonce( 'dollie_connect_ajax_nonce' ); ?>'
				  })
				})
				  .then(response => response.json())
				  .then(json => {
					if (json.success) {
					  this.message = json.data.message;
					  this.token = json.data.token;
					  this.site = json.data.site;
					  this.isSuccess = true;
					} else {
					  // Handle error response
					  this.message = json.data ?? 'An error occurred. Please try again!';
					}
					this.isLoading = false;
				  })
				  .catch(error => {
					// Handle fetch error
					this.isLoading = false;
					this.message = 'An error occurred. Please try again!';
				  });
				<?php endif; ?>
			  },

			  ':disabled'() {
				return this.isLoading
			  },
			}))
		  })
		</script>
		</div>
		<?php
	}

	/**
	 * Handle the custom setup-connection endpoint.
	 *
	 * Listens for POST requests to /?wpd-dollie-setup=1 and authenticates
	 * via Basic Auth (Application Password). This avoids REST API dependency
	 * since many hosts/plugins disable it.
	 *
	 * Called by CHQ after creating the container via Application Passwords flow.
	 * Stores the connection_id and partner_hash so the plugin knows it's connected.
	 *
	 * @since 1.0.0
	 * @return void
	 */
	public function handle_setup_connection_request() {
		if ( empty( $_GET['wpd-dollie-setup'] ) ) { // phpcs:ignore
			return;
		}

		if ( $_SERVER['REQUEST_METHOD'] !== 'POST' ) {
			wp_send_json_error( [ 'message' => 'Method not allowed.' ], 405 );
		}

		$body = json_decode( file_get_contents( 'php://input' ), true );

		// Authenticate via Basic Auth (Application Password).
		// Falls back to credentials in JSON body when hosting strips auth headers.
		$user = $this->authenticate_basic_auth();

		if ( ! $user && ! empty( $body['wp_username'] ) && ! empty( $body['wp_app_password'] ) ) {
			$user = wp_authenticate_application_password(
				null,
				sanitize_text_field( $body['wp_username'] ),
				sanitize_text_field( $body['wp_app_password'] )
			);

			if ( is_wp_error( $user ) ) {
				$user = false;
			}
		}

		if ( ! $user || ! user_can( $user, 'manage_options' ) ) {
			status_header( 401 );
			wp_send_json_error( [ 'message' => 'Unauthorized.' ] );
		}

		$connection_id = isset( $body['connection_id'] ) ? sanitize_text_field( $body['connection_id'] ) : '';
		$partner_hash  = isset( $body['partner_hash'] ) ? sanitize_text_field( $body['partner_hash'] ) : '';
		$token         = isset( $body['token'] ) ? sanitize_text_field( $body['token'] ) : '';

		if ( empty( $connection_id ) ) {
			wp_send_json_error( [ 'message' => 'Missing connection_id.' ] );
		}

		Plugin::instance()->get_host()->setup_connection( $connection_id, $partner_hash );

		// Store the auth token so the plugin can authenticate with CHQ.
		if ( $token ) {
			update_option( 'wpd_token', $token );
		}

		wp_send_json_success( [
			'message' => 'Connection configured.',
		] );
	}

	/**
	 * Handle the redirect-back callback from CHQ after plugin-active connection.
	 *
	 * CHQ redirects the admin back here with connection credentials as query
	 * parameters. Validates the CSRF state token, stores the credentials,
	 * and redirects to a clean settings URL.
	 *
	 * @since 1.0.0
	 * @return void
	 */
	public function handle_connection_callback() {
		if ( empty( $_GET['wpd-connection-callback'] ) ) { // phpcs:ignore
			return;
		}

		if ( ! current_user_can( 'manage_options' ) ) {
			return;
		}

		$connection_id = isset( $_GET['connection_id'] ) ? sanitize_text_field( wp_unslash( $_GET['connection_id'] ) ) : '';
		$partner_hash  = isset( $_GET['partner_hash'] ) ? sanitize_text_field( wp_unslash( $_GET['partner_hash'] ) ) : '';
		$token         = isset( $_GET['token'] ) ? sanitize_text_field( wp_unslash( $_GET['token'] ) ) : '';
		$state         = isset( $_GET['state'] ) ? sanitize_text_field( wp_unslash( $_GET['state'] ) ) : '';

		// Validate CSRF state parameter.
		$expected_state = get_transient( 'wpd_connection_state' );

		if ( ! $expected_state || ! hash_equals( $expected_state, $state ) ) {
			set_transient( 'wpd_connection_error', __( 'Connection failed: invalid or expired security token. Please try again.', 'dollie' ), 60 );
			wp_safe_redirect( admin_url( 'options-general.php?page=dollie-connect' ) );
			exit;
		}

		if ( empty( $connection_id ) ) {
			set_transient( 'wpd_connection_error', __( 'Connection failed: missing connection ID.', 'dollie' ), 60 );
			wp_safe_redirect( admin_url( 'options-general.php?page=dollie-connect' ) );
			exit;
		}

		// Store connection credentials.
		Plugin::instance()->get_host()->setup_connection( $connection_id, $partner_hash );

		if ( $token ) {
			update_option( 'wpd_token', $token );
		}

		// Clean up.
		delete_transient( 'wpd_connection_state' );
		set_transient( 'wpd_connection_success', __( 'Your site has been connected to Dollie.', 'dollie' ), 60 );

		wp_safe_redirect( admin_url( 'options-general.php?page=dollie-connect' ) );
		exit;
	}

	/**
	 * Authenticate the current request via HTTP Basic Auth (Application Password).
	 *
	 * @since 1.0.0
	 * @return \WP_User|false The authenticated user or false on failure.
	 */
	private function authenticate_basic_auth() {
		$username = isset( $_SERVER['PHP_AUTH_USER'] ) ? $_SERVER['PHP_AUTH_USER'] : '';
		$password = isset( $_SERVER['PHP_AUTH_PW'] ) ? $_SERVER['PHP_AUTH_PW'] : '';

		// CGI/FastCGI fallback: PHP_AUTH_USER/PW are not populated on many hosts,
		// but the Authorization header is still available. Parse it manually.
		if ( empty( $username ) ) {
			$auth_header = isset( $_SERVER['HTTP_AUTHORIZATION'] ) ? $_SERVER['HTTP_AUTHORIZATION'] : '';

			if ( empty( $auth_header ) && isset( $_SERVER['REDIRECT_HTTP_AUTHORIZATION'] ) ) {
				$auth_header = $_SERVER['REDIRECT_HTTP_AUTHORIZATION'];
			}

			if ( $auth_header && stripos( $auth_header, 'Basic ' ) === 0 ) {
				$decoded = base64_decode( substr( $auth_header, 6 ) );

				if ( $decoded !== false && strpos( $decoded, ':' ) !== false ) {
					list( $username, $password ) = explode( ':', $decoded, 2 );
				}
			}
		}

		if ( empty( $username ) || empty( $password ) ) {
			return false;
		}

		$user = wp_authenticate_application_password( null, $username, $password );

		if ( is_wp_error( $user ) ) {
			return false;
		}

		return $user;
	}

	/**
	 * Register REST API routes for connection setup.
	 *
	 * @since 1.0.0
	 * @return void
	 */
	public function register_rest_routes() {
		register_rest_route( 'dollie/v1', '/connect', [
			'methods'             => 'POST',
			'callback'            => [ $this, 'rest_handle_connect' ],
			'permission_callback' => function () {
				return current_user_can( 'manage_options' );
			},
		] );
	}

	/**
	 * Handle connection setup via REST API.
	 *
	 * WordPress core handles Application Password authentication automatically
	 * for REST API routes, so no custom auth parsing is needed.
	 *
	 * @since 1.0.0
	 * @param \WP_REST_Request $request The REST request.
	 * @return \WP_REST_Response
	 */
	public function rest_handle_connect( $request ) {
		$connection_id = sanitize_text_field( $request->get_param( 'connection_id' ) ?? '' );
		$partner_hash  = sanitize_text_field( $request->get_param( 'partner_hash' ) ?? '' );
		$token         = sanitize_text_field( $request->get_param( 'token' ) ?? '' );

		if ( empty( $connection_id ) ) {
			return new \WP_REST_Response( [ 'success' => false, 'message' => 'Missing connection_id.' ], 400 );
		}

		Plugin::instance()->get_host()->setup_connection( $connection_id, $partner_hash );

		if ( $token ) {
			update_option( 'wpd_token', $token );
		}

		return new \WP_REST_Response( [ 'success' => true, 'message' => 'Connection configured.' ], 200 );
	}

	/**
	 * Trigger update hook for the platform.
	 *
	 * Notifies CHQ that site data has changed (plugins, themes, users, etc.)
	 *
	 * @since 1.0.0
	 * @return void
	 */
	public function trigger_update_hook() {
		ChqApiClient::instance()->post( 'trigger-update' );
	}

	/**
	 * Enable auto-updates for the platform plugin.
	 *
	 * @since 1.0.0
	 * @param bool $auto_update Whether to auto-update the plugin
	 * @param object $plugin The plugin object
	 * @return bool Whether to auto-update the plugin
	 */
	public function enable_auto_update_plugin( $auto_update, $plugin ) {
		
		// Get the plugin slug
		if( ! property_exists($plugin, 'slug') || empty($plugin->slug) ) {
			
			// Check if plugin property exists before using it
			if( ! property_exists($plugin, 'plugin') || empty($plugin->plugin) ) {
				return $auto_update;
			}
			$plugin_slug = dirname( plugin_basename( $plugin->plugin ) );
		} else {
			$plugin_slug = $plugin->slug;
		}
		
		if ( 'platform' === $plugin_slug && ! Plugin::instance()->is_wpmu() ) {
			return true;
		}
		return $auto_update;
	}
}
