<?php
/**
 * Base Campaign Tile.
 *
 * Abstract base class for campaign tracker report tiles.
 *
 * @package     EDD\Pro\CampaignTracker\Admin\Reports\Endpoints\Tiles
 * @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\Admin\Reports\Endpoints\Tiles;

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

use EDD\Reports\Endpoints\Tiles\Tile;

/**
 * Base Campaign Tile Class.
 *
 * Provides common functionality for campaign tracker report tiles.
 *
 * @since 3.6.3
 */
abstract class CampaignTile extends Tile {

	/**
	 * Build campaign filter SQL based on the current filter value.
	 *
	 * @since 3.6.3
	 * @return string Campaign filter SQL clause.
	 */
	protected function get_campaign_filter_sql(): string {
		global $wpdb;

		$campaign = \EDD\Reports\get_filter_value( 'campaign_tracker' );

		// Build campaign filter SQL.
		$campaign_sql = '';
		if ( ! empty( $campaign ) ) {
			$campaign_sql = $wpdb->prepare(
				'AND campaign.meta_value = %s',
				$campaign
			);
		}

		return $campaign_sql;
	}

	/**
	 * Get the base WHERE clause for campaign queries.
	 *
	 * @since 3.6.3
	 * @return string The WHERE clause SQL.
	 */
	protected function get_base_where_clause(): string {
		global $wpdb;

		$campaign     = \EDD\Reports\get_filter_value( 'campaign_tracker' );
		$campaign_sql = $this->get_campaign_filter_sql();

		// Build the additional filter condition.
		// When filtering by a specific campaign, we don't need the EXISTS check.
		// When NOT filtering, we need to ensure orders have campaign tracking data.
		$tracking_filter = '';
		if ( empty( $campaign ) ) {
			$tracking_filter = "AND (campaign.meta_value IS NOT NULL OR EXISTS (
				SELECT 1 FROM {$wpdb->edd_ordermeta} om
				WHERE om.edd_order_id = o.id
				AND om.meta_key IN ('_eddct_campaign_source', '_eddct_campaign_medium')
			))";
		}

		return "WHERE o.type = 'sale'
			AND o.status IN('complete', 'revoked', 'partially_refunded')
			AND {$this->get_date_sql()}
			{$campaign_sql}
			{$tracking_filter}";
	}

	/**
	 * Get the base FROM clause with campaign meta join.
	 *
	 * @since 3.6.3
	 * @return string The FROM clause SQL.
	 */
	protected function get_from_clause(): string {
		global $wpdb;

		return "FROM {$wpdb->edd_orders} o
			LEFT JOIN {$wpdb->edd_ordermeta} campaign ON (o.id = campaign.edd_order_id AND campaign.meta_key = '_eddct_campaign_name')";
	}
}
