<?php
/**
 * Uninstall handler for Sugar Calendar Bookings.
 *
 * Two-phase uninstall:
 * 1. Pre-uninstall (always runs) — removes plugin infrastructure like roles.
 * 2. Uninstall (conditional on delete_data_on_uninstall) — removes data.
 *
 * @since 1.4.0
 */

// Exit if not called by WordPress.
if ( ! defined( 'WP_UNINSTALL_PLUGIN' ) ) {
	exit;
}

/*
 * -------------------------------------------------------------------------
 * Section 1: Declarations and hook registration.
 * -------------------------------------------------------------------------
 */

// Load Pro-specific uninstall if available.
$sugar_calendar_bookings_pro_uninstall = __DIR__ . '/src/Pro/uninstall.php';

if ( file_exists( $sugar_calendar_bookings_pro_uninstall ) ) {
	require_once $sugar_calendar_bookings_pro_uninstall;
}

/**
 * Delete plugin options for the current site.
 *
 * @since 1.4.0
 */
function sugar_calendar_bookings_delete_site_options() {

	delete_option( 'sugar_calendar_bookings' );
	delete_option( 'sugar_calendar_bookings_availability' );
	delete_option( 'sugar_calendar_bookings_emails' );
	delete_option( 'sugar_calendar_bookings_import' );
	delete_option( 'sugar_calendar_bookings_initial_version' );
	delete_option( 'sugar_calendar_bookings_initial_activation_time' );
	delete_option( 'sugar_calendar_bookings_activated' );
	delete_option( 'sugar_calendar_bookings_admin_notices' );
	delete_option( 'sugar_calendar_bookings_connect_token' );
	delete_option( 'sugar_calendar_bookings_connect' );
	delete_option( 'sugar_calendar_bookings_send_usage_last_run' );
	delete_option( 'scbookings_migration_state' );
}

/**
 * Delete plugin transients for the current site.
 *
 * @since 1.4.0
 */
function sugar_calendar_bookings_delete_site_transients() {

	global $wpdb;

	// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
	$wpdb->query(
		$wpdb->prepare(
			"DELETE FROM {$wpdb->options} WHERE option_name LIKE %s OR option_name LIKE %s OR option_name LIKE %s OR option_name LIKE %s",
			$wpdb->esc_like( '_transient_sugar_calendar_bookings_' ) . '%',
			$wpdb->esc_like( '_transient_scbookings_' ) . '%',
			$wpdb->esc_like( '_transient_timeout_sugar_calendar_bookings_' ) . '%',
			$wpdb->esc_like( '_transient_timeout_scbookings_' ) . '%'
		)
	);
}

/**
 * Cancel Action Scheduler tasks for the current site.
 *
 * @since 1.4.0
 */
function sugar_calendar_bookings_delete_site_scheduled_actions() {

	if ( function_exists( 'as_unschedule_all_actions' ) ) {
		as_unschedule_all_actions( '', [], 'sugar_calendar_bookings' );
	}
}

/**
 * Drop all plugin database tables.
 *
 * Finds and drops all tables matching the scbookings_ pattern.
 * Works globally — no switch_to_blog needed since SHOW TABLES
 * returns all tables in the database.
 *
 * @since 1.4.0
 */
function sugar_calendar_bookings_drop_tables() {

	global $wpdb;

	// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
	$tables = $wpdb->get_col(
		$wpdb->prepare(
			'SHOW TABLES LIKE %s',
			'%' . $wpdb->esc_like( 'scbookings_' ) . '%'
		)
	);

	// Regex guard: only drop tables matching the expected prefix pattern.
	$tables = array_filter(
		$tables,
		function ( $table ) {
			return preg_match( '/^[a-z0-9_]*scbookings_[a-z0-9_]+$/i', $table );
		}
	);

	if ( empty( $tables ) ) {
		return;
	}

	foreach ( $tables as $table ) {

		// phpcs:ignore WordPress.DB.DirectDatabaseQuery.SchemaChange, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching,WordPress.DB.PreparedSQLPlaceholders.UnsupportedIdentifierPlaceholder
		$wpdb->query( $wpdb->prepare( 'DROP TABLE IF EXISTS %i', $table ) );
	}
}

/**
 * Delete plugin user meta.
 *
 * User meta is stored in a shared table, so this only needs
 * to run once regardless of the number of sites.
 *
 * @since 1.4.0
 */
function sugar_calendar_bookings_delete_user_meta() {

	global $wpdb;

	// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
	$wpdb->query(
		$wpdb->prepare(
			"DELETE FROM {$wpdb->usermeta} WHERE meta_key LIKE %s",
			$wpdb->esc_like( 'sugar_calendar_bookings_' ) . '%'
		)
	);
}

// Per-site data cleanup (conditional).
add_action( 'sugar_calendar_bookings_uninstall_site', 'sugar_calendar_bookings_delete_site_options' );
add_action( 'sugar_calendar_bookings_uninstall_site', 'sugar_calendar_bookings_delete_site_transients' );
add_action( 'sugar_calendar_bookings_uninstall_site', 'sugar_calendar_bookings_delete_site_scheduled_actions' );

// Global data cleanup (conditional).
add_action( 'sugar_calendar_bookings_uninstall', 'sugar_calendar_bookings_drop_tables' );
add_action( 'sugar_calendar_bookings_uninstall', 'sugar_calendar_bookings_delete_user_meta' );

/**
 * Run pre-uninstall cleanup for the current site context.
 *
 * Always runs regardless of the delete_data_on_uninstall setting.
 * Removes plugin infrastructure (roles, capabilities).
 *
 * @since 1.4.0
 */
function sugar_calendar_bookings_run_pre_uninstall() {

	/**
	 * Fires during pre-uninstall for the current site context.
	 *
	 * Always runs regardless of the delete_data_on_uninstall setting.
	 * Use for removing plugin infrastructure (roles, capabilities).
	 *
	 * @since 1.4.0
	 */
	do_action( 'sugar_calendar_bookings_pre_uninstall' );
}

/**
 * Run per-site data cleanup for the current site context.
 *
 * Removes plugin options, transients, and Action Scheduler tasks.
 * Only runs when delete_data_on_uninstall is enabled.
 *
 * @since 1.4.0
 */
function sugar_calendar_bookings_run_uninstall_site() {

	/**
	 * Fires during uninstall for the current site context.
	 *
	 * Only runs when delete_data_on_uninstall is enabled.
	 * Use for removing per-site data (options, transients, tasks).
	 *
	 * @since 1.4.0
	 */
	do_action( 'sugar_calendar_bookings_uninstall_site' );
}

/**
 * Run global data cleanup.
 *
 * Removes database tables and user meta.
 * Only runs when delete_data_on_uninstall is enabled.
 *
 * @since 1.4.0
 */
function sugar_calendar_bookings_run_uninstall() {

	/**
	 * Fires during uninstall for global data cleanup.
	 *
	 * Only runs when delete_data_on_uninstall is enabled.
	 * Use for removing global data (tables, user meta).
	 *
	 * @since 1.4.0
	 */
	do_action( 'sugar_calendar_bookings_uninstall' );
}

/*
 * -------------------------------------------------------------------------
 * Section 2: Execution.
 * -------------------------------------------------------------------------
 */

// Read from the main site context intentionally — this is a network-level decision.
$sugar_calendar_bookings_options     = get_option( 'sugar_calendar_bookings', [] );
$sugar_calendar_bookings_delete_data = ! empty( $sugar_calendar_bookings_options['misc']['delete_data_on_uninstall'] );

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

	// Always: pre-uninstall per site (roles, etc.).
	foreach ( $sugar_calendar_bookings_site_ids as $sugar_calendar_bookings_site_id ) {
		switch_to_blog( $sugar_calendar_bookings_site_id );
		sugar_calendar_bookings_run_pre_uninstall();
		restore_current_blog();
	}

	// Conditional: per-site data cleanup + global data cleanup.
	if ( $sugar_calendar_bookings_delete_data ) {
		foreach ( $sugar_calendar_bookings_site_ids as $sugar_calendar_bookings_site_id ) {
			switch_to_blog( $sugar_calendar_bookings_site_id );
			sugar_calendar_bookings_run_uninstall_site();
			restore_current_blog();
		}

		sugar_calendar_bookings_run_uninstall();
	}
} else {
	sugar_calendar_bookings_run_pre_uninstall();

	if ( $sugar_calendar_bookings_delete_data ) {
		sugar_calendar_bookings_run_uninstall_site();
		sugar_calendar_bookings_run_uninstall();
	}
}
