<?php
/**
 * Answyr — First-run onboarding.
 *
 * Gets a non-technical user from activation to first value. The wall is the
 * "you need an AI API key" step — nothing drafts or answers without one. This
 * surfaces that (and the next couple of steps) as a getting-started checklist,
 * an actionable admin notice on our own screens, and a one-time redirect to
 * Settings right after activation.
 *
 * @package Answyr
 */

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

final class Answyr_Onboarding {

	public static function init(): void {
		add_action( 'admin_init', array( __CLASS__, 'maybe_redirect_after_activation' ) );
		add_action( 'admin_notices', array( __CLASS__, 'render_setup_notice' ) );
	}

	/** True once any registered provider has a key — the wall is cleared. */
	public static function is_ai_configured(): bool {
		foreach ( Answyr_Provider_Registry::all() as $provider ) {
			if ( $provider->is_configured() ) {
				return true;
			}
		}
		return false;
	}

	/**
	 * Whether the AI key wall is still up — drives the site-wide "add a key"
	 * notice and the activation redirect. Intentionally key-only: without a key
	 * nothing drafts or answers, so that's the one hard blocker we nag about.
	 */
	public static function needs_setup(): bool {
		return ! self::is_ai_configured();
	}

	/**
	 * Whether the customer-facing side is live: a ticket form/portal page or the
	 * Chat widget. Either surface satisfies the last onboarding step.
	 */
	public static function has_frontend_surface(): bool {
		if ( Answyr_Settings::module_enabled( 'chat' ) ) {
			return true;
		}
		if ( '' !== trim( (string) Answyr_Settings::get( 'portal_url', '' ) ) ) {
			return true;
		}
		return self::has_ticket_shortcode();
	}

	/** True if any published post embeds the ticket form or portal shortcode. */
	private static function has_ticket_shortcode(): bool {
		global $wpdb;
		$form   = '%' . $wpdb->esc_like( '[answyr_form' ) . '%';
		$portal = '%' . $wpdb->esc_like( '[answyr_portal' ) . '%';
		// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Admin-only, onboarding-only existence check; not worth a persistent cache that would have to be invalidated on every post edit.
		$id = $wpdb->get_var(
			$wpdb->prepare(
				"SELECT ID FROM {$wpdb->posts} WHERE post_status = 'publish' AND ( post_content LIKE %s OR post_content LIKE %s ) LIMIT 1",
				$form,
				$portal
			)
		);
		return null !== $id;
	}

	/**
	 * Whether the full getting-started checklist is done: AI key + knowledge +
	 * a customer-facing surface. Drives whether the progress card still shows.
	 */
	public static function onboarding_complete(): bool {
		return self::is_ai_configured()
			&& self::knowledge_source_count() > 0
			&& self::has_frontend_surface();
	}

	/** Published-post count across the active knowledge post types (grounding source). */
	public static function knowledge_source_count(): int {
		if ( ! class_exists( 'Answyr_Retrieval' ) ) {
			return 0;
		}
		$types = ( new Answyr_Retrieval() )->get_active_post_types();
		if ( ! $types ) {
			return 0;
		}
		$total = 0;
		foreach ( $types as $type ) {
			$counts = wp_count_posts( $type );
			$total += isset( $counts->publish ) ? (int) $counts->publish : 0;
		}
		return $total;
	}

	/** "Get a key" URL for the active provider, falling back to any that has one. */
	public static function active_key_url(): string {
		$active = Answyr_Provider_Registry::get( (string) Answyr_Settings::get( 'provider', 'anthropic' ) );
		if ( $active && '' !== $active->key_url() ) {
			return $active->key_url();
		}
		foreach ( Answyr_Provider_Registry::all() as $provider ) {
			if ( '' !== $provider->key_url() ) {
				return $provider->key_url();
			}
		}
		return '';
	}

	/** One-time bounce to Settings right after activation (single-site only). */
	public static function maybe_redirect_after_activation(): void {
		if ( ! get_transient( 'answyr_activation_redirect' ) ) {
			return;
		}
		delete_transient( 'answyr_activation_redirect' );

		// Don't hijack bulk activation, network admin, or AJAX.
		if ( wp_doing_ajax() || is_network_admin() || isset( $_GET['activate-multi'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
			return;
		}
		if ( ! current_user_can( 'manage_options' ) ) {
			return;
		}

		wp_safe_redirect( admin_url( 'admin.php?page=answyr-settings&welcome=1' ) );
		exit;
	}

	/**
	 * Actionable "add a key" notice. Shown on Answyr screens other than
	 * Settings (Settings carries the richer checklist instead), so it points a
	 * stuck user to where the key goes without nagging site-wide.
	 */
	public static function render_setup_notice(): void {
		if ( ! current_user_can( 'manage_options' ) || ! self::needs_setup() ) {
			return;
		}
		$screen = get_current_screen();
		if ( ! $screen || false === strpos( (string) $screen->id, 'answyr' ) ) {
			return;
		}
		// Settings shows the full checklist; skip the redundant banner there.
		if ( false !== strpos( (string) $screen->id, 'answyr-settings' ) ) {
			return;
		}

		$settings_url = admin_url( 'admin.php?page=answyr-settings&welcome=1' );
		printf(
			'<div class="notice notice-info"><p><strong>%1$s</strong> %2$s <a class="button button-primary" href="%3$s">%4$s</a></p></div>',
			esc_html__( 'Finish setting up Answyr.', 'answyr' ),
			esc_html__( 'Add an AI API key to start drafting grounded replies and answering chats.', 'answyr' ),
			esc_url( $settings_url ),
			esc_html__( 'Add your API key', 'answyr' )
		);
	}

	/**
	 * Getting-started checklist card. Rendered at the top of Settings (and the
	 * landing page) while setup is incomplete. Steps show live status so the user
	 * sees progress as they configure each piece.
	 */
	public static function render_checklist(): void {
		$has_key       = self::is_ai_configured();
		$has_knowledge = self::knowledge_source_count() > 0;
		$has_surface   = self::has_frontend_surface();
		$key_url       = self::active_key_url();
		$knowledge_url = admin_url( 'edit.php?post_type=answyr_kb' );

		// Order matters: a key first, then knowledge to ground it, then a
		// customer-facing surface. Chat before knowledge would answer from nothing.
		$steps = array(
			array(
				'done'  => $has_key,
				'title' => __( 'Connect an AI provider', 'answyr' ),
				'desc'  => __( 'Answyr drafts replies and answers chats with your own AI key. Add one below under API Keys.', 'answyr' ),
				'cta'   => '' !== $key_url
					? sprintf( '<a href="%s" target="_blank" rel="noopener">%s</a>', esc_url( $key_url ), esc_html__( 'Get an API key ↗', 'answyr' ) )
					: '',
			),
			array(
				'done'  => $has_knowledge,
				'title' => __( 'Add your knowledge', 'answyr' ),
				'desc'  => __( 'Replies and chat answers are grounded in your published content — without this there is nothing to answer from. Add knowledge-base articles (or point the AI at existing content under Settings → Knowledge sources).', 'answyr' ),
				'cta'   => sprintf( '<a href="%s">%s</a>', esc_url( $knowledge_url ), esc_html__( 'Add knowledge →', 'answyr' ) ),
			),
			array(
				'done'  => $has_surface,
				'title' => __( 'Put Answyr in front of customers', 'answyr' ),
				'desc'  => __( 'Add a ticket form or portal to a page with the [answyr_form] or [answyr_portal] shortcode, or turn on the Chat widget under Modules.', 'answyr' ),
				'cta'   => '',
			),
		);

		$done_count = 0;
		foreach ( $steps as $step ) {
			$done_count += $step['done'] ? 1 : 0;
		}
		?>
		<div class="answyr-card answyr-onboarding">
			<h2>
				<span class="dashicons dashicons-flag" aria-hidden="true"></span><?php esc_html_e( 'Getting started', 'answyr' ); ?>
				<span class="answyr-onboarding-progress">
					<?php
					/* translators: 1: completed step count, 2: total step count. */
					printf( esc_html__( '%1$d of %2$d done', 'answyr' ), (int) $done_count, count( $steps ) );
					?>
				</span>
			</h2>
			<p class="description"><?php esc_html_e( 'A few steps to get Answyr working. You can change any of this later.', 'answyr' ); ?></p>
			<ol class="answyr-checklist">
				<?php foreach ( $steps as $step ) : ?>
					<li class="answyr-checklist-item <?php echo $step['done'] ? 'is-done' : ''; ?>">
						<span class="answyr-checklist-mark" aria-hidden="true"><?php echo $step['done'] ? '✓' : '○'; ?></span>
						<span class="answyr-checklist-body">
							<span class="answyr-checklist-title"><?php echo esc_html( $step['title'] ); ?></span>
							<span class="answyr-checklist-desc"><?php echo esc_html( $step['desc'] ); ?></span>
							<?php if ( '' !== $step['cta'] ) : ?>
								<span class="answyr-checklist-cta"><?php echo wp_kses_post( $step['cta'] ); ?></span>
							<?php endif; ?>
						</span>
					</li>
				<?php endforeach; ?>
			</ol>
		</div>
		<?php
	}
}
