<?php
defined( 'ABSPATH' ) || exit;
/**
 * Co-installed-plugin conflict detector.
 *
 * Background
 * ----------
 * Split Pay ships under TWO distinct WP plugin slugs depending on the channel:
 *   - FREE / wp.org slug:        bsd-woo-stripe-connect-split-pay
 *   - PRO / Freemius slug:       split-pay-plugin-pro
 *
 * Both zips contain THE SAME main plugin file (bsd-split-pay-stripe-connect-woo.php)
 * with the same namespaced classes, functions, and constants. Every function
 * declaration is guarded with `if ( ! function_exists( ... ) )` so PHP never
 * fatals on a redeclaration. But that same guard means the FIRST plugin to
 * load wins — every subsequent copy of the same function is skipped.
 *
 * WordPress loads plugins in alphabetical order. `bsd-woo-stripe-connect-split-pay`
 * sorts BEFORE `split-pay-plugin-pro`, so on any site that has BOTH installed
 * and active simultaneously, the FREE copy's functions own the runtime — even
 * if the PRO copy is newer, premium-licensed, and contains hotfix code the
 * FREE copy doesn't. The customer's PRO purchase silently degrades to FREE
 * behavior with no surfaced warning.
 *
 * This pattern is impossible on Freemius-managed upgrades (the SDK auto-
 * deactivates the FREE slug when its PRO bundle is installed via the
 * dashboard), but it IS reachable when:
 *   - A merchant manually uploads the PRO zip via Plugins -> Add -> Upload
 *     onto a site that already has the FREE wp.org build active.
 *   - A site is migrated / cloned with both slugs already in active_plugins.
 *   - Composer / WP-CLI / SFTP installs both copies side by side.
 *
 * Detected on the plugin-staging Cloudways app during 3.7.5 E2E (2026-05-22).
 * Until that detection, M1/M2/M4a all appeared to silently fail because the
 * older FREE slug's pre-3.7.5 functions were winning the function_exists race.
 *
 * What this file does
 * -------------------
 * Hook admin_init at priority 0. If BOTH slugs are in active_plugins, surface
 * a high-visibility admin notice on every admin page with a one-click button
 * to deactivate the older / less-licensed copy. Choice of which to deactivate:
 *
 *   - If the PRO Freemius license is active locally (Freemius accounts option
 *     populated): keep PRO, deactivate FREE. (PRO is what the customer paid
 *     for; FREE is the no-longer-needed predecessor.)
 *   - If no PRO license: keep FREE (it's the only one with public WP.org
 *     auto-updates), deactivate PRO.
 *   - Either way: do NOT auto-deactivate. Surface the recommendation as a
 *     prominent notice with a nonce-protected one-click button. Auto-deactivation
 *     of a plugin you didn't ask for is hostile UX even when correct.
 *
 * Never fatals. Loads via the main plugin file's bootstrap pre-autoloader so
 * even sites without the namespaced classes loaded still get the notice.
 *
 * @package SplitPay\Admin
 * @since   3.7.5 (sc-7195 — co-install detector)
 */

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

if ( ! function_exists( 'spp_coinstall_get_active_spp_slugs' ) ) {
	/**
	 * Return the list of currently-active Split Pay plugin slugs (the values of
	 * `wp_content/plugins/<slug>/bsd-split-pay-stripe-connect-woo.php` entries
	 * in active_plugins). Returns 0, 1, or 2 of the known SPP slugs.
	 *
	 * @return string[] Plugin file paths (slug/main-file format).
	 */
	function spp_coinstall_get_active_spp_slugs(): array {
		$known = [
			'bsd-woo-stripe-connect-split-pay/bsd-split-pay-stripe-connect-woo.php',
			'split-pay-plugin-pro/bsd-split-pay-stripe-connect-woo.php',
		];
		$active = (array) get_option( 'active_plugins', [] );
		// Also factor in network-active on multisite.
		if ( is_multisite() ) {
			$network = (array) get_site_option( 'active_sitewide_plugins', [] );
			$active  = array_merge( $active, array_keys( $network ) );
		}
		return array_values( array_intersect( $known, $active ) );
	}
}

if ( ! function_exists( 'spp_coinstall_recommend_keep' ) ) {
	/**
	 * Decide which of the two slugs to recommend keeping when both are active.
	 * Logic: prefer the PRO slug if Freemius has a license activated locally;
	 * otherwise prefer the FREE slug (it has wp.org auto-update coverage).
	 *
	 * @return array{keep: string, deactivate: string}
	 */
	function spp_coinstall_recommend_keep(): array {
		$pro_slug  = 'split-pay-plugin-pro/bsd-split-pay-stripe-connect-woo.php';
		$free_slug = 'bsd-woo-stripe-connect-split-pay/bsd-split-pay-stripe-connect-woo.php';

		// Heuristic for "PRO license is active": the Freemius accounts option
		// has SPP's Freemius plugin_id (5491) and a non-empty license_id.
		$has_pro_license = false;
		$fs_accounts = get_option( 'fs_accounts' );
		if ( is_array( $fs_accounts ) && isset( $fs_accounts['plugin_data'] ) && is_array( $fs_accounts['plugin_data'] ) ) {
			foreach ( $fs_accounts['plugin_data'] as $plugin_data ) {
				if ( is_array( $plugin_data ) && ( $plugin_data['id'] ?? null ) == 5491 ) {
					if ( ! empty( $plugin_data['license_id'] ) || ! empty( $plugin_data['is_premium'] ) ) {
						$has_pro_license = true;
						break;
					}
				}
			}
		}

		if ( $has_pro_license ) {
			return [ 'keep' => $pro_slug, 'deactivate' => $free_slug ];
		}
		return [ 'keep' => $free_slug, 'deactivate' => $pro_slug ];
	}
}

if ( ! function_exists( 'spp_coinstall_admin_notice' ) ) {
	/**
	 * Render the admin notice when both slugs are active.
	 */
	function spp_coinstall_admin_notice(): void {
		if ( ! current_user_can( 'activate_plugins' ) ) {
			return;
		}
		$active = spp_coinstall_get_active_spp_slugs();
		if ( count( $active ) < 2 ) {
			return;
		}
		$choice         = spp_coinstall_recommend_keep();
		$deactivate_url = wp_nonce_url(
			admin_url( 'plugins.php?action=deactivate&plugin=' . urlencode( $choice['deactivate'] ) ),
			'deactivate-plugin_' . $choice['deactivate']
		);
		$keep_label       = basename( dirname( $choice['keep'] ) );
		$deactivate_label = basename( dirname( $choice['deactivate'] ) );
		?>
		<div class="notice notice-error" style="border-left-color:#dc3232;">
			<p><strong><?php esc_html_e( 'Split Pay: two copies of the plugin are active simultaneously.', 'bsd-split-pay-stripe-connect-woo' ); ?></strong></p>
			<p>
				<?php
				printf(
					/* translators: 1: kept plugin folder name, 2: deprecated plugin folder name */
					esc_html__( 'WordPress loads plugins alphabetically, so the older copy is winning the runtime and the newer copy\'s code is silently skipped. We recommend keeping %1$s and deactivating %2$s.', 'bsd-split-pay-stripe-connect-woo' ),
					'<code>' . esc_html( $keep_label ) . '</code>',
					'<code>' . esc_html( $deactivate_label ) . '</code>'
				);
				?>
			</p>
			<p>
				<a href="<?php echo esc_url( $deactivate_url ); ?>" class="button button-primary">
					<?php
					printf(
						/* translators: %s: deprecated plugin folder name */
						esc_html__( 'Deactivate %s', 'bsd-split-pay-stripe-connect-woo' ),
						esc_html( $deactivate_label )
					);
					?>
				</a>
				<a href="<?php echo esc_url( admin_url( 'plugins.php' ) ); ?>" class="button">
					<?php esc_html_e( 'Manage plugins manually', 'bsd-split-pay-stripe-connect-woo' ); ?>
				</a>
			</p>
		</div>
		<?php
	}
}

// Hook the notice on every admin page. Not gated on a specific page so the
// user can't miss it.
add_action( 'admin_notices', 'spp_coinstall_admin_notice' );
add_action( 'network_admin_notices', 'spp_coinstall_admin_notice' );
