<?php
/**
 * Uninstall routine.
 *
 * Runs only when the plugin is deleted from the Plugins screen, and only when
 * the site has opted in via the "Delete data on uninstall" setting. Deactivating
 * the plugin never removes anything.
 *
 * WordPress loads this file in isolation — the plugin itself is not bootstrapped
 * — so the key list below is deliberately self-contained rather than derived
 * from PP_Settings_Registry. Keep the two in step when adding a setting.
 *
 * @package PPE
 * @since 3.0.0
 */

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

/**
 * Option keys written by the plugin.
 *
 * @since 3.0.0
 * @return array
 */
function pp_elements_uninstall_option_keys() {
	return [
		// Core settings.
		'pp_elementor_settings',
		'pp_elementor_modules',
		'pp_elementor_extensions',
		'pp_elementor_used_modules',
		'pp_elementor_notused_modules',
		'pp_elementor_taxonomy_thumbnail_enable',
		'pp_elementor_taxonomy_thumbnail_taxonomies',

		// License.
		'pp_license_key',
		'pp_license_status',
		'pp_license_expires',
		'pp_license_user_action',

		// Integration credentials.
		'pp_fb_app_id',
		'pp_fb_app_secret',
		'pp_google_api_key',
		'pp_google_client_id',
		'pp_google_calendar_api',
		'pp_google_places_api_key',
		'pp_google_sheets_api_key',
		'pp_yelp_api_key',
		'pp_instagram_access_token',
		'pp_instagram_token_expires',
		'pp_youtube_api_key',
		'pp_recaptcha_site_key',
		'pp_recaptcha_secret_key',
		'pp_recaptcha_v3_site_key',
		'pp_recaptcha_v3_secret_key',
		'pp_enable_csv_upload',

		// Header / Footer.
		'pp_header_footer_template_header',
		'pp_header_footer_template_footer',
		'pp_header_footer_fixed_header',
		'pp_header_footer_shrink_header',
		'pp_header_footer_overlay_header',
		'pp_header_footer_overlay_header_bg',
		'pp_header_footer_fixed_header_breakpoints',

		// WooCommerce Builder.
		'pp_woo_builder_enable',
		'pp_woo_template_single_product',
		'pp_woo_template_product_archive',
		'pp_woo_recently_viewed_tracking',

		// Login / Register.
		'pp_login_page',
		'pp_register_page',
		'pp_login_register_redirect',
		'pp_login_register_logged_in_redirect',
		'pp_login_register_logged_in_page',

		// Internal state.
		'pp_elements_first_activation',
		'pp_widgets_notice_dismissed',
		'pp_templates_library',
		'pp_multisite_settings_migrated',
		'pp_override_ms',
		'pp_delete_data_on_uninstall',

		// White label flags, settable outside the UI.
		'ppwl_hide_header_footer_tab',
		'ppwl_hide_login_register_tab',
		'ppwl_remove_support_link',
		'ppwl_remove_docs_link',

		// Retired: the WooCommerce cart / checkout / thankyou / my account page
		// templates. Removed from the plugin, cleaned up here so uninstalling
		// does not leave them behind on long-lived installs.
		'pp_woo_template_product_cart',
		'pp_woo_template_product_checkout',
		'pp_woo_template_product_thankyou_page',
		'pp_woo_template_product_myaccount_page',
	];
}

/**
 * User meta keys written by the plugin.
 *
 * The registration form's 'phone' key is deliberately excluded: it is an
 * unprefixed key shared with other plugins and themes, so deleting it site-wide
 * would destroy data this plugin does not own.
 *
 * @since 3.0.0
 * @return array
 */
function pp_elements_uninstall_user_meta_keys() {
	return [
		'pp_viewed_products_ids',
		'pp_login_form_provider',
		'pp_welcome_setup_dismissed',
	];
}

/**
 * Delete every trace of the plugin from the current site.
 *
 * @since 3.0.0
 * @return void
 */
function pp_elements_uninstall_site() {
	global $wpdb;

	foreach ( pp_elements_uninstall_option_keys() as $key ) {
		delete_option( $key );
	}

	foreach ( pp_elements_uninstall_user_meta_keys() as $key ) {
		delete_metadata( 'user', 0, $key, '', true );
	}

	/*
	 * Transients are keyed dynamically (per feed, per template, per sheet), so
	 * they are matched by prefix.
	 *
	 * Only the plugin's own 'pp_' and 'ppe_' prefixes are swept. The updater
	 * also writes 'edd_sl_failed_http_*', which belongs to the shared Easy
	 * Digital Downloads licensing library — any other EDD-licensed plugin on
	 * the site writes the same prefix, so it is left alone. Those entries
	 * expire on their own.
	 */
	$prefixes = [ 'pp_', 'ppe_' ];

	foreach ( $prefixes as $prefix ) {
		$like = $wpdb->esc_like( '_transient_' . $prefix ) . '%';
		$wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->options} WHERE option_name LIKE %s", $like ) ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery

		$like = $wpdb->esc_like( '_transient_timeout_' . $prefix ) . '%';
		$wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->options} WHERE option_name LIKE %s", $like ) ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery
	}
}

/**
 * Whether the current site opted in to data deletion.
 *
 * Defaults to false: keeping data is the safe default, so an accidental delete
 * of the plugin never destroys a store's configuration.
 *
 * @since 3.0.0
 * @return bool
 */
function pp_elements_uninstall_opted_in() {
	return (bool) get_option( 'pp_delete_data_on_uninstall' );
}

if ( is_multisite() ) {
	$pp_site_ids = get_sites( [
		'fields' => 'ids',
		'number' => 0,
	] );

	foreach ( $pp_site_ids as $pp_site_id ) {
		switch_to_blog( $pp_site_id );

		// Each site keeps its own preference, so one site opting out is
		// respected even when the plugin is deleted network wide.
		if ( pp_elements_uninstall_opted_in() ) {
			pp_elements_uninstall_site();
		}

		restore_current_blog();
	}

	if ( (bool) get_site_option( 'pp_delete_data_on_uninstall' ) ) {
		foreach ( pp_elements_uninstall_option_keys() as $pp_key ) {
			delete_site_option( $pp_key );
		}
	}
} elseif ( pp_elements_uninstall_opted_in() ) {
	pp_elements_uninstall_site();
}
