<?php
/**
 * Plugin Name: Scheduled Changes for WooCommerce
 * Plugin URI:  https://github.com/joenermunch/scheduled-changes/
 * Description: Adds certified WooCommerce product scheduling to Scheduled Changes.
 * Version:     0.1.0
 * Requires at least: 6.2
 * Requires PHP: 7.4
 * Requires Plugins: woocommerce
 * Author:      Scheduled Changes
 * Author URI:  https://github.com/joenermunch/scheduled-changes
 * License:     GPL-2.0-or-later
 * License URI: https://www.gnu.org/licenses/gpl-2.0.html
 * Text Domain: jjs-post-scheduler
 *
 * @package ScheduledChangesWooCommerce
 */

// phpcs:disable WordPress.NamingConventions.PrefixAllGlobals -- scheduled_changes_wc_ is the extension prefix.
// phpcs:disable WordPress.DB -- Deactivation diagnostics read scheduler-owned tables through fixed names.
// phpcs:disable PluginCheck.Security.DirectDB -- Table names are resolved from scheduler-owned allowlists.

defined( 'ABSPATH' ) || exit;

if ( defined( 'SCHEDULED_CHANGES_WC_VERSION' ) ) {
	return;
}

define( 'SCHEDULED_CHANGES_WC_VERSION', '0.1.0' );
define( 'SCHEDULED_CHANGES_WC_MIN_CORE_VERSION', '1.0.0' );
define( 'SCHEDULED_CHANGES_WC_MIN_WOOCOMMERCE_VERSION', '8.2.0' );
define( 'SCHEDULED_CHANGES_WC_PLUGIN_FILE', __FILE__ );
define( 'SCHEDULED_CHANGES_WC_PLUGIN_BASENAME', plugin_basename( SCHEDULED_CHANGES_WC_PLUGIN_FILE ) );
define( 'SCHEDULED_CHANGES_WC_PLUGIN_DIR', plugin_dir_path( __FILE__ ) );

$scheduled_changes_wc_autoloader = SCHEDULED_CHANGES_WC_PLUGIN_DIR . 'vendor/autoload.php';

if ( is_readable( $scheduled_changes_wc_autoloader ) ) {
	require_once $scheduled_changes_wc_autoloader;
} else {
	spl_autoload_register(
		static function ( string $class_name ): void {
			$prefixes = array(
				'ScheduledChangesWooCommerce\\' => SCHEDULED_CHANGES_WC_PLUGIN_DIR . 'src/',
			);

			foreach ( $prefixes as $prefix => $source_dir ) {
				if ( 0 !== strpos( $class_name, $prefix ) ) {
					continue;
				}

				$relative = str_replace( '\\', '/', substr( $class_name, strlen( $prefix ) ) );
				$file     = $source_dir . $relative . '.php';

				if ( is_readable( $file ) ) {
					require_once $file;
				}

				return;
			}
		}
	);
}

/**
 * Prevents activation when required runtime dependencies are absent.
 */
function scheduled_changes_wc_activate(): void {
	$status = ScheduledChangesWooCommerce\DependencyStatus::current();

	if ( $status['loadable'] ) {
		return;
	}

	deactivate_plugins( SCHEDULED_CHANGES_WC_PLUGIN_BASENAME );
	wp_die( esc_html( $status['message'] ) );
}

register_activation_hook( SCHEDULED_CHANGES_WC_PLUGIN_FILE, 'scheduled_changes_wc_activate' );

/**
 * Records recoverable deactivation context without blocking emergency recovery.
 */
function scheduled_changes_wc_deactivate(): void {
	$count = scheduled_changes_wc_active_recording_count();

	if ( $count <= 0 ) {
		delete_option( scheduled_changes_wc_deactivation_notice_option() );
		return;
	}

	update_option(
		scheduled_changes_wc_deactivation_notice_option(),
		array(
			'activeRecordings' => $count,
			'recordedAt'       => gmdate( 'c' ),
			'message'          => __(
				'Scheduled Changes for WooCommerce was deactivated while WooCommerce Record Changes sessions were active. Reactivate the extension to finish, abandon, or clean up those sessions before uninstalling.',
				'jjs-post-scheduler'
			),
		),
		false
	);
}

/**
 * Returns the extension-owned deactivation recovery option name.
 */
function scheduled_changes_wc_deactivation_notice_option(): string {
	return 'scheduled_changes_wc_deactivation_recovery_notice';
}

/**
 * Counts active WooCommerce-owned recording sessions without loading services.
 */
function scheduled_changes_wc_active_recording_count(): int {
	if ( ! class_exists( ScheduledChanges\Database\TableNames::class ) ) {
		return 0;
	}

	global $wpdb;

	$table = ( new ScheduledChanges\Database\TableNames() )->get( 'recording_sessions' );

	return (int) $wpdb->get_var(
		$wpdb->prepare(
			"SELECT COUNT(*)
			FROM {$table}
			WHERE status = %s
				AND expires_at_utc >= %s
				AND (source_provider_id = %s OR workspace_provider_id = %s)",
			'active',
			gmdate( 'Y-m-d H:i:s' ),
			'woocommerce-core',
			'woocommerce-core'
		)
	);
}

/**
 * Shows a recovery warning after the extension is reactivated.
 */
function scheduled_changes_wc_deactivation_recovery_notice(): void {
	if ( ! is_admin() || ! current_user_can( 'activate_plugins' ) ) {
		return;
	}

	$notice = get_option( scheduled_changes_wc_deactivation_notice_option(), array() );

	if ( ! is_array( $notice ) || (int) ( $notice['activeRecordings'] ?? 0 ) <= 0 ) {
		return;
	}

	if ( scheduled_changes_wc_active_recording_count() <= 0 ) {
		delete_option( scheduled_changes_wc_deactivation_notice_option() );
		return;
	}

	printf(
		'<div class="notice notice-warning"><p>%s</p></div>',
		esc_html( (string) ( $notice['message'] ?? '' ) )
	);
}

register_deactivation_hook( SCHEDULED_CHANGES_WC_PLUGIN_FILE, 'scheduled_changes_wc_deactivate' );
add_action( 'admin_notices', 'scheduled_changes_wc_deactivation_recovery_notice' );

add_action(
	'before_woocommerce_init',
	static function (): void {
		if ( class_exists( Automattic\WooCommerce\Utilities\FeaturesUtil::class ) ) {
			Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility(
				'custom_order_tables',
				SCHEDULED_CHANGES_WC_PLUGIN_FILE,
				true
			);
		}
	}
);

add_action(
	'plugins_loaded',
	static function (): void {
		ScheduledChangesWooCommerce\Bootstrap::boot( SCHEDULED_CHANGES_WC_PLUGIN_FILE );
	},
	15
);
