<?php
/**
 * Gates plugin update downloads behind a current (active, non-expired) license.
 *
 * Updates remain visible in WordPress when the license is inactive or expired;
 * only the download package is removed and upgrade attempts are blocked.
 *
 * Premium feature access uses {@see wp_powersuite_is_license_valid()}.
 * Updates and support use {@see wp_powersuite_is_license_current()}.
 *
 * @package WP_PowerSuite
 * @since 1.0.0
 */

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

/**
 * @since 1.0.0
 */
final class WPPS_License_Updates {

	/**
	 * Register update filters and admin notices.
	 */
	public static function register(): void {
		add_filter( 'site_transient_update_plugins', [ self::class, 'filter_update_transient' ], 20 );
		add_filter( 'transient_update_plugins', [ self::class, 'filter_update_transient' ], 20 );
		add_filter( 'upgrader_pre_download', [ self::class, 'block_unlicensed_download' ], 10, 3 );
		add_filter( 'upgrader_pre_download', [ self::class, 'verified_package_download' ], 15, 3 );
		add_action( 'admin_notices', [ self::class, 'render_update_admin_notices' ] );
		add_action( 'admin_notices', [ self::class, 'render_insecure_ssl_warning' ] );
	}

	/**
	 * Download + verify integrity for WP PowerSuite packages (TLS always verified).
	 *
	 * @param bool|\WP_Error $reply
	 * @param string         $package
	 * @param \WP_Upgrader   $upgrader
	 * @return bool|\WP_Error|string
	 */
	public static function verified_package_download( $reply, string $package, $upgrader ) {
		if ( ! class_exists( 'WPPS_Package_Integrity', false ) ) {
			return $reply;
		}

		return WPPS_Package_Integrity::download_and_verify( $reply, $package, $upgrader );
	}

	/**
	 * Persistent admin warning when insecure SSL diagnostics are enabled.
	 */
	public static function render_insecure_ssl_warning(): void {
		if ( ! current_user_can( 'manage_options' ) ) {
			return;
		}
		if ( ! defined( 'WP_POWERSUITE_LICENSE_ALLOW_INSECURE_SSL' ) || ! WP_POWERSUITE_LICENSE_ALLOW_INSECURE_SSL ) {
			return;
		}
		echo '<div class="notice notice-error"><p>';
		echo esc_html__(
			'WP_POWERSUITE_LICENSE_ALLOW_INSECURE_SSL is enabled. This constant is for temporary license-server diagnostics only. It never applies to plugin package downloads, and it must not be left enabled in production.',
			'wp-powersuite'
		);
		echo '</p></div>';
	}

	/**
	 * Public wrapper for package-attempt detection (integrity verifier).
	 *
	 * @param string       $package  Package URL.
	 * @param \WP_Upgrader $upgrader Upgrader instance.
	 */
	public static function is_wpps_update_package( string $package, $upgrader ): bool {
		return self::is_wpps_update_attempt( $package, $upgrader );
	}

	/**
	 * Keep WP PowerSuite updates visible but strip package when license is not current.
	 *
	 * @param mixed $value Update transient value.
	 * @return mixed
	 */
	public static function filter_update_transient( $value ) {
		if ( ! is_object( $value ) || ! defined( 'WP_POWERSUITE_PLUGIN_FILE' ) ) {
			return $value;
		}

		if ( ! class_exists( 'WPPS_License_Updater', false ) ) {
			return $value;
		}

		$plugin_file = plugin_basename( WP_POWERSUITE_PLUGIN_FILE );
		if ( empty( $value->response[ $plugin_file ] ) || ! is_object( $value->response[ $plugin_file ] ) ) {
			return $value;
		}

		$value->response[ $plugin_file ] = WPPS_License_Updater::apply_download_gate( $value->response[ $plugin_file ] );

		return $value;
	}

	/**
	 * Block plugin package download when license is not current.
	 *
	 * @param bool|\WP_Error $reply   False to proceed, WP_Error to abort.
	 * @param string         $package Package URL.
	 * @param \WP_Upgrader   $upgrader Upgrader instance.
	 * @return bool|\WP_Error
	 */
	public static function block_unlicensed_download( $reply, string $package, $upgrader ) {
		if ( $reply !== false || ! class_exists( 'WPPS_License_Updater', false ) ) {
			return $reply;
		}

		if ( WPPS_License_Updater::can_download_updates() ) {
			return $reply;
		}

		if ( ! self::is_wpps_update_attempt( $package, $upgrader ) ) {
			return $reply;
		}

		return new WP_Error(
			'wpps_license_update_blocked',
			WPPS_License_Updater::get_download_block_message()
		);
	}

	/**
	 * Show update-available notices on Dashboard, Plugins, and Updates screens.
	 */
	public static function render_update_admin_notices(): void {
		if ( ! current_user_can( 'update_plugins' ) || ! class_exists( 'WPPS_License_Updater', false ) ) {
			return;
		}

		if ( ! self::is_notice_screen() ) {
			return;
		}

		$pending = WPPS_License_Updater::get_pending_update();
		if ( ! is_array( $pending ) ) {
			return;
		}

		$message = WPPS_License_Updater::get_update_available_notice_message( $pending );
		if ( $message === '' ) {
			return;
		}

		$notice_class = ! empty( $pending['can_download'] ) ? 'notice-info' : 'notice-warning';
		$license_url  = ! empty( $pending['license_url'] ) ? (string) $pending['license_url'] : '';

		echo '<div class="notice ' . esc_attr( $notice_class ) . ' is-dismissible wpps-license-update-admin-notice"><p>';
		echo esc_html( $message );
		if ( $license_url !== '' && empty( $pending['can_download'] ) ) {
			echo ' <a href="' . esc_url( $license_url ) . '">';
			esc_html_e( 'Go to License page', 'wp-powersuite' );
			echo '</a>';
		}
		echo '</p></div>';
	}

	/**
	 * Whether the current admin screen should show update notices.
	 */
	private static function is_notice_screen(): bool {
		if ( ! function_exists( 'get_current_screen' ) ) {
			return false;
		}

		$screen = get_current_screen();
		if ( ! is_object( $screen ) || empty( $screen->id ) ) {
			return false;
		}

		if ( class_exists( 'WPPS_License_Manager', false ) ) {
			$page = isset( $_GET['page'] ) ? sanitize_key( wp_unslash( $_GET['page'] ) ) : '';
			if ( $page === WPPS_License_Manager::get_license_page_slug() ) {
				return false;
			}
		}

		return in_array( $screen->id, [ 'dashboard', 'plugins', 'update-core', 'plugins-network' ], true );
	}

	/**
	 * Detect when the upgrader is downloading WP PowerSuite.
	 *
	 * @param string       $package  Package URL.
	 * @param \WP_Upgrader $upgrader Upgrader instance.
	 */
	private static function is_wpps_update_attempt( string $package, $upgrader ): bool {
		if ( ! defined( 'WP_POWERSUITE_PLUGIN_FILE' ) ) {
			return false;
		}

		$basename = plugin_basename( WP_POWERSUITE_PLUGIN_FILE );

		if ( is_object( $upgrader ) && isset( $upgrader->skin ) && is_object( $upgrader->skin ) ) {
			if ( ! empty( $upgrader->skin->plugin ) && (string) $upgrader->skin->plugin === $basename ) {
				return true;
			}

			if (
				! empty( $upgrader->skin->plugin_info['file'] )
				&& (string) $upgrader->skin->plugin_info['file'] === $basename
			) {
				return true;
			}
		}

		$stashed = WPPS_License_Updater::get_stashed_package_url();
		if ( $stashed !== '' && $package === $stashed ) {
			return true;
		}

		return false;
	}
}
