<?php
/**
 * Background tasks performed via Action Scheduler. All the tasks can be found in Tools > Scheduled Actions.
 * Some of the background tasks aren't here but within their modules. "logs clear", "usage data", and "notifications update" tasks.
 *
 * @since 3.21.0
 */

namespace AAWP;

/**
 * The BackgroundTasks Class.
 *
 * @since 3.21.0
 */
class BackgroundTasks {

	/**
	 * Initialize background tasks.
	 *
	 * @since 3.21.0
	 */
	public function init() {

		// Disable if CRON is disabled.
		if ( ! empty( get_option( 'aawp_tools' )['deactivate_as'] ) || apply_filters( 'aawp_tools_disable_action_scheduler', false ) ) {
			return;
		}

		add_action( 'admin_init', [ $this, 'schedule' ] );
		add_action( 'aawp_execute_database_garbage_collection', 'aawp_execute_database_garbage_collection' );
		add_action( 'aawp_delete_product_images_cache', 'aawp_delete_product_images_cache' );
		add_action( 'aawp_execute_products_lists_renew_cache', 'aawp_execute_renew_cache' );
		add_action( 'aawp_execute_rating_renew_cache', 'aawp_renew_rating_cache_event' );
		add_action( 'aawp_execute_single_renew_cache_event', [ $this, 'renew_cache' ] );
		add_action( 'aawp_single_verify_api_credentials_event', 'aawp_maybe_verify_stored_api_credentials' );
		add_action( 'aawp_process_site_stripe_migration', [ $this, 'process_site_stripe_migration' ] );
		add_action( 'aawp_site_stripe_migration_posts', [ $this, 'migrate_post' ] );
		add_action( 'aawp_site_stripe_migration_widgets', [ $this, 'migrate_widget' ] );
	}

	/**
	 * Schedule the tasks.
	 *
	 * @since 3.21.0
	 */
	public function schedule() {

		// Database Garbase Collection.
		if ( empty( aawp_get_option( 'disable_database_garbage_collection', 'general' ) ) && false === as_next_scheduled_action( 'aawp_execute_database_garbage_collection' ) ) {
			as_schedule_recurring_action( strtotime( '+1 hour' ), HOUR_IN_SECONDS, 'aawp_execute_database_garbage_collection', [], 'aawp' );
		}

		// Product local image cache.
		if ( aawp_is_product_local_images_enabled() && false === as_next_scheduled_action( 'aawp_delete_product_images_cache' ) ) {
			as_schedule_recurring_action( strtotime( '+1 day' ), DAY_IN_SECONDS, 'aawp_delete_product_images_cache', [], 'aawp' );
		}

		// Products & lists renew.
		if ( false === as_next_scheduled_action( 'aawp_execute_products_lists_renew_cache' ) ) {
			as_schedule_recurring_action( time(), MINUTE_IN_SECONDS * 5, 'aawp_execute_products_lists_renew_cache', [], 'aawp' );
		}

		// Ratings Renew.
		if ( false === as_next_scheduled_action( 'aawp_execute_rating_renew_cache' ) ) {
			as_schedule_recurring_action( time(), MINUTE_IN_SECONDS * 5, 'aawp_execute_rating_renew_cache', [], 'aawp' );
		}
	}

	/**
	 * Renew Products & Rating Cache.
	 * Runs on single event, once the "Renew Cache" button is clicked. aawp_renew_cache() function schedules a single event
	 * which runs this method.
	 *
	 * @since 3.21.0
	 */
	public function renew_cache() {

		// Renew Products & Lists.
		aawp_execute_renew_cache( true );

		// Renew Ratings.
		aawp_renew_rating_cache_event();
	}

	/**
	 * Process site stripe migration task.
	 *
	 * @since 3.40.1
	 */
	public function process_site_stripe_migration() {
		( new Admin\Tools\Migrations() )->process_site_stripe_migration();
	}

	/**
	 * Migrate Site Stripe Links in a post.
	 *
	 * @param int $post_id The Post id to migrate the Stripe Links of.
	 *
	 * @since 3.40.2
	 */
	public function migrate_post( $post_id ) {

		$content = apply_filters( 'the_content', get_post_field( 'post_content', $post_id ) );

		// Get updated content or false if Site Stripe Links not found.
		$replaced_ss_content = ( new Admin\Tools\Migrations() )->replace_site_stripe_links( $content );

		// If Site Stripe links doesn't exit, use post content else use replaced content.
		$replaced_ss_iframe_content = false === (bool) $replaced_ss_content ? ( new Admin\Tools\Migrations() )->replace_site_stripe_iframes( $content ) : ( new Admin\Tools\Migrations() )->replace_site_stripe_iframes( $replaced_ss_content );

		// Only update the post if only the post content is changed.
		if ( ! empty( $replaced_ss_content ) || ! empty( $replaced_ss_iframe_content ) ) {

			$updated_post = [
				'ID'           => $post_id,
				'post_content' => ! empty( $replaced_ss_iframe_content ) ? $replaced_ss_iframe_content : $replaced_ss_content,
			];

			// Update the post.
			$result = wp_update_post( $updated_post );

			if ( 0 != $result ) {
				/* translators: %d - Post ID */
				aawp_log( 'Site Stripe Migration', sprintf( __( 'Migration completed for Post # %d', 'aawp' ), $post_id ) );
			}
		}
	}

	/**
	 * Migrate Site Stripe Links in a widget.
	 *
	 * @param string $widget_name The Widget name to migrate the Stripe Links of.
	 *
	 * @since 3.40.2
	 */
	public function migrate_widget( $widget_name ) {

		$widgets        = get_option( $widget_name );
		$updated_widget = [];

		foreach ( $widgets as $key => $widget ) {

			if ( empty( $widget['content'] ) ) {
				$updated_widget[ $key ] = $widget;
				continue;
			}

			// Get updated content or false if Site Stripe Links not found.
			$replaced_ss_content = ( new Admin\Tools\Migrations() )->replace_site_stripe_links( $widget['content'] );

			// If Site Stripe links doesn't exit, use post content else use replaced content.
			$replaced_ss_iframe_content = false === (bool) $replaced_ss_content ? ( new Admin\Tools\Migrations() )->replace_site_stripe_iframes( $widget['content'] ) : ( new Admin\Tools\Migrations() )->replace_site_stripe_iframes( $replaced_ss_content );

			// Only update the widget if it's content is changed.
			if ( ! empty( $replaced_ss_content ) || ! empty( $replaced_ss_iframe_content ) ) {
				/* translators: %s - Widget name */
				aawp_log( 'Site Stripe Migration', sprintf( __( 'Migration completed for Widget - %s', 'aawp' ), $widget_name ) );

				$widget['content'] = ! empty( $replaced_ss_iframe_content ) ? $replaced_ss_iframe_content : $replaced_ss_content;
			}

			$updated_widget[ $key ] = $widget;
		}//end foreach

		update_option( $widget_name, $updated_widget );
	}

	/**
	 * Cancel all the AS actions for a group "aawp".
	 *
	 * @since 3.21.0
	 *
	 * @return void
	 */
	public function cancel_all() {

		if ( class_exists( 'ActionScheduler_DBStore' ) ) {
			\ActionScheduler_DBStore::instance()->cancel_actions_by_group( 'aawp' );
		}
	}
}
