<?php
/**
 * PufferGo 遥测与反馈 - 五类事件：下载、激活、停用、卸载、反馈
 *
 * 不依赖 API Key，直接向 api.puffergo.com 上报；服务端会记录 clientIp。
 *
 * @package PufferGo
 * @since 1.0.0
 */

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

/**
 * Class PufferGo_Telemetry
 */
class PufferGo_Telemetry {

	/**
	 * 注册全局脚本：为后台/块编辑器注入 window.puffergoTelemetry（apiFetch 错误上报用）
	 *
	 * @return void
	 */
	public static function register_hooks() {
		add_action( 'admin_enqueue_scripts', array( __CLASS__, 'enqueue_global_telemetry_context' ), 1 );
		add_action( 'enqueue_block_editor_assets', array( __CLASS__, 'enqueue_global_telemetry_context' ), 1 );
		add_action( 'puffergo_send_error_event_async', array( __CLASS__, 'handle_async_error_event' ) );
	}

	/**
	 * 在页面早期输出遥测基址与站点环境（仅具备 edit_posts 的已登录用户）
	 *
	 * @return void
	 */
	public static function enqueue_global_telemetry_context() {
		if ( ! is_user_logged_in() || ! current_user_can( 'edit_posts' ) ) {
			return;
		}
		// 幂等保护：admin_enqueue_scripts 与 enqueue_block_editor_assets 在块编辑器页面都会触发
		static $done = false;
		if ( $done ) {
			return;
		}
		$done    = true;
		$handle  = 'puffergo-telemetry-context';
		$version = defined( 'PUFFERGO_CORE_VERSION' ) ? PUFFERGO_CORE_VERSION : '1.0.0';
		wp_register_script( $handle, false, array(), $version, false );
		wp_enqueue_script( $handle );
		$payload = array(
			'baseUrl' => rtrim( self::get_api_base_url(), '/' ),
			'env'     => self::get_env_payload(),
		);
		wp_add_inline_script(
			$handle,
			'window.puffergoTelemetry=' . wp_json_encode( $payload, JSON_UNESCAPED_UNICODE ) . ';',
			'after'
		);
	}

	/**
	 * WP-Cron 异步回调：实际执行 HTTP 上报。
	 *
	 * @param array<string, mixed> $payload 待发送的完整 payload（含 eventType）。
	 * @return void
	 */
	public static function handle_async_error_event( array $payload ) {
		self::send_event( $payload );
	}

	/**
	 * 获取遥测 API 基础 URL（与 API 客户端一致）
	 *
	 * @return string
	 */
	public static function get_api_base_url() {
		return defined( 'PUFFERGO_AI_PAGE_BUILDER_BASE_URL' )
			? PUFFERGO_AI_PAGE_BUILDER_BASE_URL
			: 'https://api.puffergo.com';
	}

	/**
	 * 获取当前环境信息（domain、php、wp、puffergo 版本）
	 *
	 * @return array<string, string>
	 */
	public static function get_env_payload() {
		return array(
			'domain'         => home_url(),
			'phpVersion'     => PHP_VERSION,
			'wpVersion'      => get_bloginfo( 'version' ),
			'pufferGoVersion' => defined( 'PUFFERGO_CORE_VERSION' ) ? PUFFERGO_CORE_VERSION : '',
		);
	}

	/**
	 * 上报下载事件（首次激活时发送一次，表示插件已就绪/已获取）
	 */
	public static function send_download_event() {
		$payload = array_merge(
			array( 'eventType' => 'download' ),
			self::get_env_payload()
		);
		self::send_event( $payload );
	}

	/**
	 * 上报激活事件（插件激活时调用）
	 */
	public static function send_activate_event() {
		$payload = array_merge(
			array( 'eventType' => 'activate' ),
			self::get_env_payload()
		);
		self::send_event( $payload );
	}

	/**
	 * 上报停用事件（用户点击停用时立即发送，带原因）
	 *
	 * @param string $reason        停用原因（可选）
	 * @param string $reason_detail 停用原因详情（可选）
	 */
	public static function send_deactivate_event( $reason = '', $reason_detail = '' ) {
		$payload = array_merge(
			array(
				'eventType'             => 'deactivate',
				'uninstallReason'       => is_string( $reason ) ? $reason : '',
				'uninstallReasonDetail' => is_string( $reason_detail ) ? $reason_detail : '',
			),
			self::get_env_payload()
		);
		self::send_event( $payload );
	}

	/**
	 * 上报卸载事件（uninstall.php 中调用，删除插件时再发一次）
	 *
	 * @param string $reason        卸载原因（可选）
	 * @param string $reason_detail 卸载原因详情（可选）
	 */
	public static function send_uninstall_event( $reason = '', $reason_detail = '' ) {
		$payload = array_merge(
			array(
				'eventType'             => 'uninstall',
				'uninstallReason'       => is_string( $reason ) ? $reason : '',
				'uninstallReasonDetail' => is_string( $reason_detail ) ? $reason_detail : '',
			),
			self::get_env_payload()
		);
		self::send_event( $payload );
	}

	/**
	 * 发送单条事件到遥测 API（内部使用）。失败或非 2xx 时重试一次。
	 *
	 * @param array<string, string> $payload 完整请求体（含 eventType 与 env）
	 */
	private static function send_event( $payload ) {
		$url  = self::get_api_base_url() . '/api/telemetry/event';
		$body = wp_json_encode( $payload );
		if ( $body === false ) {
			return;
		}
		$args = array(
			'headers' => array(
				'Content-Type' => 'application/json; charset=utf-8',
			),
			'body'    => $body,
			'timeout' => 5,
		);
		$response = wp_remote_post( $url, $args );
		if ( is_wp_error( $response ) ) {
			$response = wp_remote_post( $url, $args );
		}
		if ( is_wp_error( $response ) ) {
			return;
		}
		$code = wp_remote_retrieve_response_code( $response );
		$code = is_numeric( $code ) ? (int) $code : 0;
		// 仅对 5xx 重试一次，4xx 不重试
		if ( $code >= 500 && $code < 600 ) {
			wp_remote_post( $url, $args );
		}
	}

	/**
	 * 上报插件侧检测到的错误（PHP / 远端 API），经 siteForge /api/telemetry/event → Axiom。
	 * 通过 WP-Cron 异步执行，不阻塞当前请求。
	 *
	 * @param array<string, mixed> $detail 结构化详情（须可 JSON 编码）。
	 * @return void
	 */
	public static function send_error_event( array $detail ) {
		if ( empty( $detail ) ) {
			return;
		}
		$json = wp_json_encode( $detail, JSON_UNESCAPED_UNICODE );
		if ( false === $json ) {
			return;
		}
		$payload = array_merge(
			array(
				'eventType' => 'error',
				'content'   => $json,
			),
			self::get_env_payload()
		);
		// 通过 WP-Cron 异步发送，不阻塞当前 PHP 请求（尤其是已经 503 的场景）
		wp_schedule_single_event( time(), 'puffergo_send_error_event_async', array( $payload ) );
	}

	/**
	 * 获取「反馈」页面 URL（跳转到管理后台收集反馈，带环境参数）
	 *
	 * 可通过 wp-config.php 定义 PUFFERGO_FEEDBACK_BASE_URL 覆盖（例如 https://puffergo.com/dashboard）
	 *
	 * @return string
	 */
	public static function get_feedback_url() {
		$base = defined( 'PUFFERGO_FEEDBACK_BASE_URL' ) ? PUFFERGO_FEEDBACK_BASE_URL : ( defined( 'PUFFERGO_BASE_URL' ) ? PUFFERGO_BASE_URL : 'https://puffergo.com' );
		$base = rtrim( $base, '/' );
		$args = array(
			'domain'          => home_url(),
			'php_version'     => PHP_VERSION,
			'wp_version'      => get_bloginfo( 'version' ),
			'puffergo_version' => defined( 'PUFFERGO_CORE_VERSION' ) ? PUFFERGO_CORE_VERSION : '',
		);
		return $base . '/feedback?' . http_build_query( $args );
	}
}
