<?php
/**
 * AI Insights Page.
 *
 * Two AI tools that read the plugin's own data via DataDigest:
 *   • Weekly Briefing — a one-click executive SEO summary.
 *   • Ask your data — a co-pilot that answers questions about the site.
 * Admin-triggered, grounded in real numbers, nothing written to the site.
 *
 * @package Platform\Helm\Modules\Ai
 */

declare( strict_types = 1 );

namespace Platform\Helm\Modules\Ai;

use Platform\Helm\Core\Authorization;
use Platform\Helm\Core\LlmClient;
use Platform\Helm\Core\LlmSettings;

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

final class AiInsightsPage {

	public const PAGE_SLUG    = 'platform-helm-ai-insights';
	public const PARENT_SLUG  = 'platform-helm';
	public const NONCE        = 'platform_helm_ai_insights';
	private const BRIEF_OPTION = 'platform_helm_ai_last_brief';

	public function register_hooks(): void {
		add_action( 'admin_menu', [ $this, 'register_menu' ], 47 );
		add_action( 'admin_enqueue_scripts', [ $this, 'enqueue' ] );
		add_action( 'wp_ajax_platform_helm_ai_brief', [ $this, 'ajax_brief' ] );
		add_action( 'wp_ajax_platform_helm_ai_ask', [ $this, 'ajax_ask' ] );
	}

	/**
	 * This screen's markup uses the shared SEO-reports component set (.ph-gsc),
	 * so it needs gsc.css in addition to the global Helm admin.css. Loaded only on
	 * this page.
	 */
	public function enqueue( string $hook ): void {
		unset( $hook );
		// phpcs:ignore WordPress.Security.NonceVerification.Recommended
		$page = isset( $_GET['page'] ) ? sanitize_key( wp_unslash( (string) $_GET['page'] ) ) : '';
		if ( self::PAGE_SLUG !== $page ) {
			return;
		}
		wp_enqueue_style(
			'platform-helm-gsc',
			PLATFORM_HELM_URL . 'assets/css/gsc.css',
			[],
			PLATFORM_HELM_VERSION
		);
	}

	public function register_menu(): void {
		if ( ! Authorization::is_master_admin() ) {
			return;
		}
		add_submenu_page(
			self::PARENT_SLUG,
			__( 'AI Insights', 'platform-helm' ),
			__( 'AI Insights', 'platform-helm' ),
			'manage_options',
			self::PAGE_SLUG,
			[ $this, 'render' ]
		);
	}

	public function ajax_brief(): void {
		check_ajax_referer( self::NONCE, 'nonce' );
		Authorization::require_master_admin_ajax();

		$system = 'You are an in-house SEO analyst for this website. '
			. 'Using ONLY the site data provided, write this week\'s executive SEO briefing for the platform manager. '
			. "Use these plain-text sections, each with a short heading:\n"
			. "HEADLINE — one line on overall direction.\n"
			. "KEY WINS — what is going well.\n"
			. "RISKS / ISSUES — what is hurting performance.\n"
			. "OPPORTUNITIES — ranked, naming the specific pages/queries from the data.\n"
			. "RECOMMENDED ACTIONS — 3 to 5 concrete, prioritised next steps.\n"
			. 'Reference the actual numbers, pages and queries given. Be specific and tight, executive tone. '
			. 'If a section has no supporting data, say so in one line rather than inventing anything.';

		$res = LlmClient::chat(
			[
				[ 'role' => 'system', 'content' => $system ],
				[ 'role' => 'user', 'content' => "SITE DATA:\n" . DataDigest::text() ],
			],
			[ 'max_tokens' => 900, 'temperature' => 0.4 ]
		);
		if ( is_wp_error( $res ) ) {
			wp_send_json_error( [ 'message' => $res->get_error_message() ] );
		}

		update_option( self::BRIEF_OPTION, [ 'time' => time(), 'text' => $res ], false );
		wp_send_json_success( [ 'brief' => $res, 'time' => __( 'just now', 'platform-helm' ) ] );
	}

	public function ajax_ask(): void {
		check_ajax_referer( self::NONCE, 'nonce' );
		Authorization::require_master_admin_ajax();

		$question = isset( $_POST['question'] ) ? sanitize_textarea_field( wp_unslash( $_POST['question'] ) ) : '';
		if ( '' === trim( $question ) ) {
			wp_send_json_error( [ 'message' => __( 'Type a question first.', 'platform-helm' ) ] );
		}

		$system = 'You are an in-house SEO analyst for this website. Answer the user\'s question using ONLY the site data below. '
			. 'Reference the actual pages, queries and numbers. If the data does not contain the answer, say what is missing and how to get it '
			. '(e.g. run the Content Auditor, sync Search Console). Be concise and practical. No invented facts.';

		$res = LlmClient::chat(
			[
				[ 'role' => 'system', 'content' => $system ],
				[ 'role' => 'user', 'content' => "SITE DATA:\n" . DataDigest::text() . "\n\nQUESTION: " . $question ],
			],
			[ 'max_tokens' => 650, 'temperature' => 0.4 ]
		);
		if ( is_wp_error( $res ) ) {
			wp_send_json_error( [ 'message' => $res->get_error_message() ] );
		}
		wp_send_json_success( [ 'answer' => $res ] );
	}

	public function render(): void {
		Authorization::require_master_admin();
		$nonce = wp_create_nonce( self::NONCE );
		?>
		<div class="wrap ph-gsc">
			<h1><?php esc_html_e( 'AI Insights', 'platform-helm' ); ?></h1>
			<p class="ph-gsc-lead"><?php esc_html_e( 'Your in-house SEO analyst, reading this plugin\'s own data — audit scores, Search Console, cannibalization and link health. Everything here is generated on demand; nothing is sent on public page loads.', 'platform-helm' ); ?></p>

			<?php if ( ! LlmSettings::is_configured() ) : ?>
				<div class="notice notice-warning inline"><p>
					<?php
					printf(
						/* translators: %s: settings URL */
						wp_kses_post( __( 'Connect an AI key first under <a href="%s">AI Assistant</a>.', 'platform-helm' ) ),
						esc_url( admin_url( 'admin.php?page=platform-helm-ai' ) )
					);
					?>
				</p></div>
				</div>
				<?php
				return;
			endif;

			$last = get_option( self::BRIEF_OPTION, null );
			?>

			<div class="ph-gsc-card">
				<div class="ph-gsc-row" style="justify-content:space-between; align-items:center; flex-wrap:wrap; gap:10px;">
					<h2 style="margin:0;"><?php esc_html_e( 'Weekly Briefing', 'platform-helm' ); ?></h2>
					<button type="button" class="button button-primary" id="ph-ai-brief-btn"><?php esc_html_e( 'Generate this week\'s briefing', 'platform-helm' ); ?></button>
				</div>
				<p class="ph-gsc-hint" id="ph-ai-brief-meta">
					<?php
					if ( is_array( $last ) && ! empty( $last['time'] ) ) {
						echo esc_html( sprintf( /* translators: %s time-ago */ __( 'Last generated %s ago.', 'platform-helm' ), human_time_diff( (int) $last['time'], time() ) ) );
					} else {
						esc_html_e( 'Not generated yet.', 'platform-helm' );
					}
					?>
				</p>
				<div id="ph-ai-brief-out" class="ph-ai-out" style="<?php echo ( is_array( $last ) && ! empty( $last['text'] ) ) ? '' : 'display:none;'; ?>"><?php echo esc_html( is_array( $last ) ? (string) ( $last['text'] ?? '' ) : '' ); ?></div>
			</div>

			<div class="ph-gsc-card">
				<h2 style="margin-top:0;"><?php esc_html_e( 'Ask your data', 'platform-helm' ); ?></h2>
				<p class="ph-gsc-hint"><?php esc_html_e( 'Ask anything about the site\'s SEO state. Examples: "What are my 5 highest-upside refreshes?" · "Which cannibalized query should I fix first?" · "Is my click trend up or down?"', 'platform-helm' ); ?></p>
				<div id="ph-ai-chat" class="ph-ai-chat"></div>
				<div class="ph-gsc-row" style="gap:8px; align-items:flex-start;">
					<textarea id="ph-ai-q" class="widefat" rows="2" placeholder="<?php esc_attr_e( 'Ask a question about your SEO data…', 'platform-helm' ); ?>"></textarea>
					<button type="button" class="button button-primary" id="ph-ai-ask-btn"><?php esc_html_e( 'Ask', 'platform-helm' ); ?></button>
				</div>
			</div>

			<script>
			( function () {
				var ajaxUrl = <?php echo wp_json_encode( admin_url( 'admin-ajax.php' ) ); ?>;
				var nonce   = <?php echo wp_json_encode( $nonce ); ?>;

				function post( action, extra ) {
					var body = new URLSearchParams();
					body.append( 'action', action );
					body.append( 'nonce', nonce );
					Object.keys( extra || {} ).forEach( function ( k ) { body.append( k, extra[ k ] ); } );
					return fetch( ajaxUrl, { method: 'POST', credentials: 'same-origin', body: body } ).then( function ( r ) { return r.json(); } );
				}

				var briefBtn = document.getElementById( 'ph-ai-brief-btn' );
				briefBtn.addEventListener( 'click', function () {
					var out = document.getElementById( 'ph-ai-brief-out' );
					var meta = document.getElementById( 'ph-ai-brief-meta' );
					briefBtn.disabled = true; var lbl = briefBtn.textContent; briefBtn.textContent = 'Reading your data…';
					out.style.display = ''; out.textContent = 'Generating…';
					post( 'platform_helm_ai_brief', {} ).then( function ( res ) {
						briefBtn.disabled = false; briefBtn.textContent = lbl;
						if ( res && res.success && res.data ) { out.textContent = res.data.brief; if ( meta ) { meta.textContent = 'Last generated just now.'; } }
						else { out.textContent = ( res && res.data && res.data.message ) ? res.data.message : 'Could not generate.'; }
					} ).catch( function () { briefBtn.disabled = false; briefBtn.textContent = lbl; out.textContent = 'Request failed — try again.'; } );
				} );

				var askBtn = document.getElementById( 'ph-ai-ask-btn' );
				var qEl    = document.getElementById( 'ph-ai-q' );
				var chat   = document.getElementById( 'ph-ai-chat' );
				function bubble( who, text, cls ) {
					var d = document.createElement( 'div' );
					d.className = 'ph-ai-bubble ' + cls;
					var w = document.createElement( 'div' ); w.className = 'ph-ai-who'; w.textContent = who;
					var b = document.createElement( 'div' ); b.className = 'ph-ai-text'; b.textContent = text;
					d.appendChild( w ); d.appendChild( b ); chat.appendChild( d ); chat.scrollTop = chat.scrollHeight;
					return b;
				}
				function ask() {
					var q = qEl.value.trim();
					if ( ! q ) { return; }
					bubble( 'You', q, 'is-you' );
					qEl.value = '';
					var ans = bubble( 'Analyst', 'Thinking…', 'is-ai' );
					askBtn.disabled = true;
					post( 'platform_helm_ai_ask', { question: q } ).then( function ( res ) {
						askBtn.disabled = false;
						ans.textContent = ( res && res.success && res.data ) ? res.data.answer : ( ( res && res.data && res.data.message ) ? res.data.message : 'Could not answer.' );
						chat.scrollTop = chat.scrollHeight;
					} ).catch( function () { askBtn.disabled = false; ans.textContent = 'Request failed — try again.'; } );
				}
				askBtn.addEventListener( 'click', ask );
				qEl.addEventListener( 'keydown', function ( e ) { if ( e.key === 'Enter' && ( e.metaKey || e.ctrlKey ) ) { e.preventDefault(); ask(); } } );
			}() );
			</script>

			<style>
			.ph-ai-out { white-space:pre-wrap; line-height:1.55; background:#fff; border:1px solid #e0e6ee; border-radius:6px; padding:14px; margin-top:10px; }
			.ph-ai-chat { display:flex; flex-direction:column; gap:8px; margin:10px 0; max-height:380px; overflow-y:auto; }
			.ph-ai-bubble { border-radius:8px; padding:8px 12px; max-width:90%; }
			.ph-ai-bubble.is-you { align-self:flex-end; background:#eef3fb; }
			.ph-ai-bubble.is-ai { align-self:flex-start; background:#f3fbf5; border:1px solid #d8ecdd; }
			.ph-ai-who { font-size:11px; font-weight:600; color:#646970; margin-bottom:2px; }
			.ph-ai-text { white-space:pre-wrap; line-height:1.5; }
			</style>
		</div>
		<?php
	}
}
