<?php
/**
 * Campaign Meta Migration
 *
 * Migrates serialized campaign data to individual meta fields for improved reporting.
 *
 * @package     EDD\Pro\CampaignTracker\Upgrades
 * @copyright   Copyright (c) 2025, Sandhills Development, LLC
 * @license     https://opensource.org/licenses/gpl-2.0.php GNU Public License
 * @since       3.6.3
 */

namespace EDD\Pro\CampaignTracker\Upgrades;

// Exit if accessed directly.
defined( 'ABSPATH' ) || exit; // @codeCoverageIgnore

use EDD\Upgrades\Background\Upgrade;
use EDD\Cron\Events\SingleEvent;

/**
 * CampaignMetaMigration Class
 *
 * @since 3.6.3
 */
class CampaignMetaMigration extends Upgrade {
	use \EDD\Pro\CampaignTracker\Campaigns\Traits\Order;

	/**
	 * The number of database rows which should prevent the upgrade running via the background process.
	 *
	 * @var int
	 */
	protected $warning_count = 25000;

	/**
	 * Gets the name of the upgrade.
	 *
	 * @since 3.6.3
	 * @return string
	 */
	public static function get_upgrade_name(): string {
		return 'edd_campaign_meta_migration';
	}

	/**
	 * Gets the items to process.
	 *
	 * @since 3.6.3
	 * @param bool $count If we should return the count of items.
	 * @return array|int|false
	 */
	public function get_items( $count = false ) {
		global $wpdb;

		if ( $count ) {
			return absint(
				$wpdb->get_var(
					"SELECT COUNT(DISTINCT o.id)
					FROM {$wpdb->prefix}edd_orders o
					INNER JOIN {$wpdb->prefix}edd_ordermeta campaign ON (o.id = campaign.edd_order_id AND campaign.meta_key = 'eddct_campaign')
					LEFT JOIN {$wpdb->prefix}edd_ordermeta name ON (o.id = name.edd_order_id AND name.meta_key = '_eddct_campaign_name')
					WHERE o.type = 'sale'
					AND name.meta_id IS NULL"
				)
			);
		}

		$results = $wpdb->get_col(
			"SELECT DISTINCT o.id
			FROM {$wpdb->prefix}edd_orders o
			INNER JOIN {$wpdb->prefix}edd_ordermeta campaign ON (o.id = campaign.edd_order_id AND campaign.meta_key = 'eddct_campaign')
			LEFT JOIN {$wpdb->prefix}edd_ordermeta name ON (o.id = name.edd_order_id AND name.meta_key = '_eddct_campaign_name')
			WHERE o.type = 'sale'
			AND name.meta_id IS NULL
			LIMIT 50"
		);

		return ! empty( $results ) ? array_map( 'absint', $results ) : array();
	}

	/**
	 * Processes the upgrade step.
	 *
	 * @since 3.6.3
	 * @return void
	 */
	public function process_step(): void {
		if ( ! $this->can_process_step() ) {
			return;
		}

		$items = $this->get_items();
		if ( empty( $items ) ) {
			$this->mark_complete();
			return;
		}

		foreach ( $items as $order_id ) {
			$campaign_info = edd_get_order_meta( $order_id, 'eddct_campaign', true );

			if ( empty( $campaign_info ) || ! is_array( $campaign_info ) ) {
				continue;
			}

			$this->add_meta( $order_id, $campaign_info );
		}

		$this->add_or_update_initial_notification();

		// Schedule the next step.
		SingleEvent::add(
			time() + MINUTE_IN_SECONDS,
			self::get_cron_action()
		);
	}

	/**
	 * Gets the array of parameters for the complete notification.
	 *
	 * @since 3.6.3
	 * @return array
	 */
	public function get_complete_notification(): array {
		return array(
			'title'   => __( 'Campaign Data Migration Complete!', 'easy-digital-downloads' ),
			'content' => __( 'Campaign Tracker has finished updating campaign data for your orders. Enhanced reporting is now available.', 'easy-digital-downloads' ),
		);
	}

	/**
	 * Gets the array of parameters for the in progress notification.
	 *
	 * @since 3.6.3
	 * @return array
	 */
	public function get_in_progress_notification(): array {
		return array(
			/* translators: %d: Percentage complete */
			'title'   => __( 'Updating Campaign Data ( %d%% )', 'easy-digital-downloads' ),
			'content' => __( 'Campaign Tracker is updating campaign data for your orders. This will enable enhanced reporting capabilities. We\'ll let you know when the process is complete.', 'easy-digital-downloads' ),
		);
	}

	/**
	 * Gets the array of parameters for the CLI notification.
	 *
	 * @since 3.6.3
	 * @return array
	 */
	public function get_cli_notification(): array {
		return array(
			'title'   => __( 'Database Update Required', 'easy-digital-downloads' ),
			'content' => sprintf(
				/* translators: %s is the CLI command to run */
				__( 'Campaign Tracker needs to update campaign data for your orders, but due to the number of records, you should run this via CLI using <code>%s</code>.', 'easy-digital-downloads' ),
				'wp edd upgrade ' . self::get_upgrade_name()
			),
		);
	}
}
