<?php
/**
 * SocialPromoter wiring for the vendored BWD Support Copilot widget.
 *
 * ALL SocialPromoter-specific configuration for the copilot lives here: the
 * module in includes/support-copilot/ is host-agnostic and is vendored VERBATIM
 * from its canonical home (01-Plugin-Repos/70-Shared-Modules/bwd-support-copilot,
 * GitHub blackandwhitedigital/bwd-support-copilot) - never edit the vendored copy
 * in place, and never add SocialPromoter knowledge to it.
 *
 * This file ships in BOTH builds. It is not listed in the main plugin file's
 * paid-edition-only path directive, and the bootstrap requires it at file scope
 * rather than from inside a licence-gated block: the licence layer physically
 * removes the files it is told are paid-edition-only, and a removed require would
 * fatal every free install. The assistant authorises with the support hub via the
 * site's Freemius install id or an admin-entered token, so no credential ships in
 * the zip and the hub tiers usage server-side.
 *
 * SocialPromoter's own AI copy drafting is a paid-edition feature and its client
 * class is absent from the free build, so no local_ai bridge is wired here at all.
 * Module 2.0.2 therefore suppresses the "add your own AI" onboarding prompt, which
 * this host could not honour in the free build.
 *
 * The Support screen is registered through the admin class's submenu seam
 * (pkits_sp_admin_submenu_pages).
 *
 * @package PublisherKits_SocialPromoter
 * @since   1.52.0
 */

defined( 'ABSPATH' ) || exit;

/**
 * Class PKITS_SP_Support_Copilot_Boot
 */
class PKITS_SP_Support_Copilot_Boot {

	/**
	 * Admin capability for every Support surface.
	 *
	 * SocialPromoter's admin pages pass 'manage_options' literally, so the value is
	 * centralised here for the copilot's own surfaces rather than repeated inline.
	 *
	 * @var string
	 */
	const CAP = 'manage_options';

	/**
	 * Register SocialPromoter's vendored module copy with the newest-wins loader
	 * and schedule the config queue.
	 *
	 * Registration only - no translated strings here. This runs early so this copy
	 * takes part in the loader's newest-wins negotiation; the config (which builds
	 * translated strings) is queued on `init` by init() below, where a text domain
	 * may safely be loaded.
	 *
	 * @return void
	 */
	public static function register() {
		static $done = false;
		if ( $done ) {
			return;
		}
		$done = true;

		require_once PKITS_SP_DIR . 'includes/support-copilot/support-copilot.php';
		add_action( 'init', array( __CLASS__, 'init' ), 5 );
	}

	/**
	 * Queue SocialPromoter's widget config and attach the Support screen.
	 *
	 * Runs on `init` because the config carries translated strings, and loading a
	 * text domain before `init` is doing_it_wrong. A queue() arriving after the
	 * loader has booted is boot-ed immediately by the loader, so this is safe.
	 *
	 * @return void
	 */
	public static function init() {
		static $queued = false;
		if ( $queued ) {
			return;
		}
		$queued = true;

		\BlackWhiteDigital\SupportCopilot\Loader::queue(
			array(
				'id'                  => 'pkits_sp',
				'slug'                => 'publisherkits-socialpromoter',
				'version'             => PKITS_SP_VERSION,
				'display_name'        => __( 'PublisherKits Support Copilot', 'publisherkits-socialpromoter' ),
				'endpoint_default'    => 'https://bwtlsupport.com/wp-json/bwsa/v1',
				'endpoint_option'     => 'pkits_sp_copilot_endpoint',
				'token_option'        => 'pkits_sp_copilot_token',
				'consent_option'      => 'pkits_sp_copilot_consent',
				'capability'          => self::CAP,
				'settings_capability' => self::CAP,
				'capability_check'    => array( __CLASS__, 'user_can' ),
				'freemius_install_id' => array( __CLASS__, 'freemius_install_id' ),
				'activation_url'      => array( __CLASS__, 'activation_url' ),
				// No local_ai / local_ai_available / connectors_url: SocialPromoter's
				// AI copy drafting is a paid-edition feature whose client is absent
				// from the free build, so the BYOK prompt would be a promise this
				// host could not keep. Module 2.0.2 hides it when these are omitted.
				'is_plugin_screen'    => array( __CLASS__, 'is_sp_screen' ),
				// Scalar config FLAGS only, verified against the settings save handler
				// in class-sp-admin.php. Deliberately excluded: nudge_post_types and
				// nudge_roles (arrays, and the module takes scalars only), and
				// copy_template - it is author-written text that can carry brand
				// wording, so it is treated as content and never leaves the site.
				'settings_keys'       => array(
					'pkits_sp_settings.nudge_enabled',
					'pkits_sp_settings.nudge_banner_enabled',
					'pkits_sp_settings.auto_cancel_on_delete',
					'pkits_sp_settings.debug_logging',
					'pkits_sp_settings.delete_data_on_uninstall',
				),
				'diagnostics'         => array( __CLASS__, 'diagnostics' ),
				'suite'               => array( __CLASS__, 'suite_manifest' ),
				'accent'              => '#f0b56a',
				'strings'             => self::strings(),
			)
		);

		add_filter( 'pkits_sp_admin_submenu_pages', array( __CLASS__, 'add_submenu_page' ) );
		add_action( 'admin_post_pkits_sp_save_copilot_settings', array( __CLASS__, 'handle_save' ) );
	}

	/**
	 * The booted widget instance. Null until the loader has negotiated and booted.
	 *
	 * @return \BlackWhiteDigital\SupportCopilot\Copilot|null
	 */
	public static function instance() {
		return class_exists( '\BlackWhiteDigital\SupportCopilot\Loader' )
			? \BlackWhiteDigital\SupportCopilot\Loader::instance( 'pkits_sp' )
			: null;
	}

	/**
	 * Is the given admin screen one of SocialPromoter's? Every screen hangs off the
	 * 'publisherkits-socialpromoter' menu slug, so every screen id CONTAINS that
	 * string - matched by substring, never by an exact screen id, which varies with
	 * the menu position and the translated menu title.
	 *
	 * @param WP_Screen $screen Current screen.
	 * @return bool
	 */
	public static function is_sp_screen( $screen ) {
		return is_object( $screen ) && false !== strpos( (string) $screen->id, 'publisherkits-socialpromoter' );
	}

	/**
	 * Module capability gate routed through the host. It stays a named host
	 * callable so the module never calls current_user_can directly.
	 *
	 * @param string $capability Capability the module is checking.
	 * @return bool
	 */
	public static function user_can( $capability ) {
		return current_user_can( $capability );
	}

	/**
	 * The site's Freemius install id for licence-based auto-authorisation. When > 0
	 * the module authorises with the support hub using the install id instead of an
	 * admin-pasted token. Returns 0 until the site is registered with Freemius, in
	 * which case the module falls back to token mode.
	 *
	 * @return int
	 */
	public static function freemius_install_id() {
		if ( ! function_exists( 'pkits_sp_fs' ) ) {
			return 0;
		}
		$fs = pkits_sp_fs();
		if ( ! is_object( $fs ) || ! method_exists( $fs, 'is_registered' ) || ! $fs->is_registered() ) {
			return 0;
		}
		$site = method_exists( $fs, 'get_site' ) ? $fs->get_site() : null;
		return ( is_object( $site ) && ! empty( $site->id ) ) ? (int) $site->id : 0;
	}

	/**
	 * SocialPromoter's Freemius opt-in/activation URL, linked from the
	 * unauthorised-state onboarding prompt. Empty when Freemius is unavailable, in
	 * which case the module omits the activate prompt.
	 *
	 * @return string
	 */
	public static function activation_url() {
		if ( ! function_exists( 'pkits_sp_fs' ) ) {
			return '';
		}
		$fs = pkits_sp_fs();
		if ( is_object( $fs ) && method_exists( $fs, 'get_activation_url' ) ) {
			return (string) $fs->get_activation_url();
		}
		return '';
	}

	/**
	 * Read-only diagnostics extras sent with each chat message.
	 *
	 * Whitelist discipline is strict: ONLY counts and configured-service labels are
	 * reported. Nothing that identifies a connected account leaves the site - no
	 * handle, page name, account id, token or OAuth credential - and neither does
	 * any post content, composed copy or scheduled-post text. Platforms are
	 * reported as the set of platform slugs that have at least one active account,
	 * which tells support which connectors to reason about without naming anyone.
	 *
	 * @return array
	 */
	public static function diagnostics() {
		$out = array();

		// Which platforms are connected at all, as slugs only, plus a count.
		if ( class_exists( 'PKITS_SP_Accounts' ) && method_exists( 'PKITS_SP_Accounts', 'get_active_by_platform' ) ) {
			$connected = array();
			$total     = 0;
			foreach ( array( 'x', 'linkedin', 'facebook', 'bluesky' ) as $platform ) {
				$accounts = (array) PKITS_SP_Accounts::get_active_by_platform( $platform );
				$count    = count( $accounts );
				if ( $count > 0 ) {
					$connected[] = $platform;
					$total      += $count;
				}
			}
			$out['platforms_connected'] = implode( ',', $connected );
			$out['accounts_active']     = $total;
		}

		// Queue scale as counts only - never the copy or the linked post.
		global $wpdb;
		$table = $wpdb->prefix . 'pkits_sp_queue';
		// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared
		$exists = $wpdb->get_var( $wpdb->prepare( 'SHOW TABLES LIKE %s', $table ) );
		if ( $exists === $table ) {
			// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared
			$out['queue_pending'] = (int) $wpdb->get_var( "SELECT COUNT(*) FROM {$table} WHERE status = 'pending'" );
			// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared
			$out['queue_sent'] = (int) $wpdb->get_var( "SELECT COUNT(*) FROM {$table} WHERE status = 'sent'" );
			// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared
			$out['queue_failed'] = (int) $wpdb->get_var( "SELECT COUNT(*) FROM {$table} WHERE status = 'failed'" );
		}

		// Edition is deliberately NOT reported from here. The support hub derives it
		// from the site's licence when it authorises the request, so sending it would
		// be redundant - and reading a licence constant would put a licence-derived
		// flag into the free package, which this plugin removed at the reviewer's
		// request and must not reintroduce.
		return $out;
	}

	/**
	 * Suite manifest: the other active PublisherKits plugins and their versions, so
	 * support can see the whole suite a question is being asked from.
	 *
	 * @return array [ [slug, version], ... ]
	 */
	public static function suite_manifest() {
		if ( ! function_exists( 'get_plugins' ) ) {
			require_once ABSPATH . 'wp-admin/includes/plugin.php';
		}

		$manifest = array();
		foreach ( (array) get_option( 'active_plugins', array() ) as $basename ) {
			$slug = dirname( $basename );
			if ( '.' === $slug || 'publisherkits-socialpromoter' === $slug ) {
				continue;
			}
			if ( 0 !== strpos( $slug, 'publisherkits-' ) ) {
				continue;
			}
			$file = WP_PLUGIN_DIR . '/' . $basename;
			if ( ! file_exists( $file ) ) {
				continue;
			}
			$data       = get_plugin_data( $file, false, false );
			$manifest[] = array(
				'slug'    => $slug,
				'version' => (string) ( isset( $data['Version'] ) ? $data['Version'] : '' ),
			);
		}
		return $manifest;
	}

	// ---------------------------------------------------------------------------
	// Support screen (hung on the admin class's submenu seam)
	// ---------------------------------------------------------------------------

	/**
	 * Contribute the Support submenu page (pkits_sp_admin_submenu_pages).
	 *
	 * @param array $pages Submenu page definitions.
	 * @return array
	 */
	public static function add_submenu_page( $pages ) {
		if ( ! is_array( $pages ) ) {
			return $pages;
		}
		$pages[] = array(
			'page_title' => __( 'SocialPromoter — Support', 'publisherkits-socialpromoter' ),
			'menu_title' => __( 'Support', 'publisherkits-socialpromoter' ),
			'capability' => self::CAP,
			'menu_slug'  => 'publisherkits-socialpromoter-support',
			'callback'   => array( __CLASS__, 'render_page' ),
		);
		return $pages;
	}

	/**
	 * Render the Support screen: the vendored widget's settings fields wrapped in
	 * SocialPromoter's own page furniture, form and nonce.
	 *
	 * @return void
	 */
	public static function render_page() {
		if ( ! current_user_can( self::CAP ) ) {
			return;
		}
		$copilot = self::instance();

		// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- display-only notice flag set by our own redirect.
		$notice = isset( $_GET['pkits_sp_copilot'] ) ? sanitize_key( wp_unslash( $_GET['pkits_sp_copilot'] ) ) : '';
		?>
		<div class="wrap pkits-sp-admin">
			<h1 class="pkits-sp-page-title"><span class="pkits-sp-logo-mark">SP</span><?php esc_html_e( 'SocialPromoter — Support', 'publisherkits-socialpromoter' ); ?></h1>
			<hr class="wp-header-end">

			<?php if ( 'saved' === $notice ) : ?>
				<div class="notice notice-success is-dismissible">
					<p><?php esc_html_e( 'Support settings saved.', 'publisherkits-socialpromoter' ); ?></p>
				</div>
			<?php elseif ( 'error' === $notice ) : ?>
				<div class="notice notice-error is-dismissible">
					<p><?php esc_html_e( 'Support settings could not be saved. Please reload the page and try again.', 'publisherkits-socialpromoter' ); ?></p>
				</div>
			<?php endif; ?>

			<h2><?php esc_html_e( 'Support Copilot', 'publisherkits-socialpromoter' ); ?></h2>
			<p><?php esc_html_e( 'The Support Copilot is the floating Help button on every SocialPromoter screen. It opens a popup chat that answers usage and setup questions instantly, grounded in documentation matched to your installed version. It is read-only: it can explain, but it can never change anything, and it never reads the content of your posts. Your connected account names and handles, your post copy and your scheduled posts are never sent.', 'publisherkits-socialpromoter' ); ?></p>

			<?php
			if ( ! $copilot ) {
				echo '<p>' . esc_html__( 'The Support Copilot module is not loaded.', 'publisherkits-socialpromoter' ) . '</p>';
				echo '</div>';
				return;
			}

			if ( ! $copilot->is_configured() ) {
				echo '<div class="notice notice-warning inline"><p>' . esc_html__( 'This site is not yet authorised for support answers. Activate SocialPromoter (licence) to switch on free monthly answers automatically, or paste a support token below. Either way, the Help button still opens with setup guidance.', 'publisherkits-socialpromoter' ) . '</p></div>';
			}
			?>

			<form method="post" action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>">
				<?php
				wp_nonce_field( 'pkits_sp_copilot_save', 'pkits_sp_copilot_nonce' );
				echo '<input type="hidden" name="action" value="pkits_sp_save_copilot_settings" />';
				$copilot->render_settings_fields();
				submit_button( __( 'Save support settings', 'publisherkits-socialpromoter' ) );
				?>
			</form>
		</div>
		<?php
	}

	/**
	 * Process a Support settings save (admin_post). The host verifies its outer
	 * nonce and capability here, co-located with the input this handler reads; the
	 * module's save_settings() re-checks its own nonce and the settings capability
	 * and sanitises every field.
	 *
	 * @return void
	 */
	public static function handle_save() {
		if ( ! current_user_can( self::CAP ) ) {
			wp_die( esc_html__( 'You are not allowed to change support assistant settings.', 'publisherkits-socialpromoter' ), '', array( 'response' => 403 ) );
		}
		check_admin_referer( 'pkits_sp_copilot_save', 'pkits_sp_copilot_nonce' );

		$copilot = self::instance();
		$result  = 'error';
		if ( $copilot ) {
			// Sanitised field-by-field inside save_settings(), which also re-verifies
			// its own nonce and the settings capability.
			// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
			$saved  = $copilot->save_settings( wp_unslash( $_POST ) );
			$result = is_wp_error( $saved ) ? 'error' : 'saved';
		}

		wp_safe_redirect(
			add_query_arg(
				array(
					'page'             => 'publisherkits-socialpromoter-support',
					'pkits_sp_copilot' => $result,
				),
				admin_url( 'admin.php' )
			)
		);
		exit;
	}

	/**
	 * Translated UI strings for the widget (module defaults are plain English; i18n
	 * happens here so the vendored module stays text-domain-free).
	 *
	 * No BYOK strings are supplied: SocialPromoter wires no local_ai bridge, so
	 * module 2.0.2 suppresses that prompt and hint entirely.
	 *
	 * @return array
	 */
	private static function strings() {
		return array(
			'launcher_label'                   => __( 'Help', 'publisherkits-socialpromoter' ),
			'launcher_title'                   => __( 'Open the PublisherKits support assistant (answers usage and setup questions on this screen, no page change)', 'publisherkits-socialpromoter' ),
			'panel_subtitle'                   => __( 'Instant answers about SocialPromoter', 'publisherkits-socialpromoter' ),
			'consent_heading'                  => __( 'Before you start', 'publisherkits-socialpromoter' ),
			/* translators: %host%: hostname of the support service endpoint (replaced by the widget, not by sprintf). */
			'consent_body'                     => __( 'To provide support, this assistant sends to %host%: your question and recent chat history; your site address and, where available, its licence installation identifier, used to authorise the request and apply fair-use limits; the plugin version and those of the other PublisherKits plugins installed; the admin screen you are on; and a short whitelist of non-sensitive settings and counts (which social platforms have a connected account, how many accounts and how many queued, sent and failed posts exist, and five on/off settings covering reminders, queue auto-cancel, debug logging and uninstall clean-up). Your social accounts and content are never sent: no account name, handle, page name, access token or API key leaves your site, and neither does the text of any post you have written or scheduled, nor your copy template. The assistant cannot change anything on your site. Ordinary questions are not kept after they are answered; only if you choose "Send to support" is the conversation retained, so that it can become a support ticket.', 'publisherkits-socialpromoter' ),
			'consent_accept'                   => __( 'Agree and start chatting', 'publisherkits-socialpromoter' ),
			'consent_accept_hint'              => __( 'Records your agreement for this whole site and enables the assistant for everyone who can use it. Only a user who can manage SocialPromoter settings can accept. You can withdraw consent on the Support screen.', 'publisherkits-socialpromoter' ),
			'greeting'                         => __( 'Hi! Ask me anything about setting up or using SocialPromoter - connecting X, LinkedIn, Facebook or Bluesky, composing and scheduling posts, or reading your post history. I answer from documentation matched to your installed version.', 'publisherkits-socialpromoter' ),
			'input_placeholder'                => __( 'Type your question…', 'publisherkits-socialpromoter' ),
			'send'                             => __( 'Send', 'publisherkits-socialpromoter' ),
			'thinking'                         => __( 'Thinking…', 'publisherkits-socialpromoter' ),
			'error_generic'                    => __( 'Sorry - the assistant could not be reached. Please try again in a moment.', 'publisherkits-socialpromoter' ),
			'soft_gate'                        => __( 'Usage and setup questions are handled right here in the assistant. Support tickets are prioritised for bugs, billing and data issues.', 'publisherkits-socialpromoter' ),
			'escalate_anyway'                  => __( 'Still need to raise a ticket?', 'publisherkits-socialpromoter' ),
			'escalate_offer'                   => __( 'Not solved? You can send this conversation to the support team.', 'publisherkits-socialpromoter' ),
			'escalate_button'                  => __( 'Send to support', 'publisherkits-socialpromoter' ),
			'escalate_confirm_label'           => __( 'Your email for ticket replies', 'publisherkits-socialpromoter' ),
			'escalate_confirm_hint'            => __( 'The full chat transcript and the diagnostic snapshot are attached to the ticket so support can see what was already tried.', 'publisherkits-socialpromoter' ),
			'escalate_send'                    => __( 'Create ticket', 'publisherkits-socialpromoter' ),
			'escalate_cancel'                  => __( 'Cancel', 'publisherkits-socialpromoter' ),
			'escalated_prefix'                 => __( 'Ticket created:', 'publisherkits-socialpromoter' ),
			'close_title'                      => __( 'Close the assistant (your conversation is kept until you leave this page)', 'publisherkits-socialpromoter' ),
			'new_chat'                         => __( 'New chat', 'publisherkits-socialpromoter' ),
			'new_chat_title'                   => __( 'Clear this conversation and start again', 'publisherkits-socialpromoter' ),
			'disabled_notice'                  => __( 'The assistant is not available: no support token is configured.', 'publisherkits-socialpromoter' ),
			/* translators: %d: number of free hub-answered questions remaining this month (replaced by the widget, not by sprintf). */
			'allowance_left'                   => __( '%d free assistant answer(s) left this month on this site.', 'publisherkits-socialpromoter' ),
			'consent_denied'                   => __( 'Only a user who can manage SocialPromoter settings can enable the assistant for this site.', 'publisherkits-socialpromoter' ),
			'settings_error_cap'               => __( 'You are not allowed to change support assistant settings.', 'publisherkits-socialpromoter' ),
			'settings_error_nonce'             => __( 'Security check failed - please reload the page and try again.', 'publisherkits-socialpromoter' ),
			'settings_error_https'             => __( 'The support endpoint must be an https:// URL.', 'publisherkits-socialpromoter' ),
			'settings_token_label'             => __( 'Support token', 'publisherkits-socialpromoter' ),
			'settings_token_ph_set'            => __( '•••••••• (a token is set - leave blank to keep it)', 'publisherkits-socialpromoter' ),
			'settings_token_ph_unset'          => __( 'Paste the widget token supplied with your licence', 'publisherkits-socialpromoter' ),
			/* translators: %state%: "enabled" or "disabled" (replaced by the widget, not by sprintf). */
			'settings_token_desc'              => __( 'Authorises this site\'s assistant with the PublisherKits support service. The assistant stays %state% until a valid token is entered or the site is activated via its licence. The token is stored in this site\'s database and sent only to the support endpoint below - never to the browser.', 'publisherkits-socialpromoter' ),
			'settings_state_enabled'           => __( 'enabled', 'publisherkits-socialpromoter' ),
			'settings_state_disabled'          => __( 'disabled', 'publisherkits-socialpromoter' ),
			'settings_token_clear_label'       => __( 'Clear the stored token (turns off token-based access).', 'publisherkits-socialpromoter' ),
			'settings_endpoint_label'          => __( 'Support endpoint', 'publisherkits-socialpromoter' ),
			'settings_endpoint_desc'           => __( 'Base URL of the support service the assistant talks to (must be https://). Leave blank to use the default shown below. Only change this if PublisherKits tells you to.', 'publisherkits-socialpromoter' ),
			'settings_mode_label'              => __( 'Answer mode', 'publisherkits-socialpromoter' ),
			'settings_mode_hub_title'          => __( 'Support service', 'publisherkits-socialpromoter' ),
			'settings_mode_hub_desc'           => __( 'Questions are answered by the PublisherKits support service, using documentation matched to your installed version. Your connected accounts and post content are never sent.', 'publisherkits-socialpromoter' ),
			'settings_consent_label'           => __( 'Privacy consent', 'publisherkits-socialpromoter' ),
			/* translators: %date%: the date consent was accepted, Y-m-d (replaced by the widget, not by sprintf). */
			'settings_consent_accepted'        => __( 'Accepted on this site on %date%.', 'publisherkits-socialpromoter' ),
			'settings_consent_accepted_nodate' => __( 'Accepted on this site.', 'publisherkits-socialpromoter' ),
			'settings_consent_withdraw'        => __( 'Withdraw consent. The assistant will show the privacy notice again before the next chat; nothing is sent to the support service until someone re-accepts.', 'publisherkits-socialpromoter' ),
			'settings_consent_pending'         => __( 'Not yet accepted. Before the first chat, the assistant shows a notice explaining exactly what is sent (your question plus a read-only, non-sensitive snapshot that contains no account names, handles or post content); a user who can manage SocialPromoter settings must agree before anything is sent.', 'publisherkits-socialpromoter' ),
			'onboard_heading'                  => __( 'Get instant answers about SocialPromoter', 'publisherkits-socialpromoter' ),
			'onboard_activate_body'            => __( 'Activate SocialPromoter to switch on your free monthly assistant answers. Activation registers this site with the licence service so the support assistant can answer your usage and setup questions - no payment needed, and you can stop any time.', 'publisherkits-socialpromoter' ),
			'onboard_activate_cta'             => __( 'Activate for free answers', 'publisherkits-socialpromoter' ),
		);
	}
}
