<?php
/**
 * Fundraiser Admin Widgets
 *
 * Registers dashboard widgets for fundraising statistics, based on ambassador-core
 *
 * @package AmbassadorHub\Admin
 */

namespace AmbassadorHub\Fundraisers\Admin;

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQL.NotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter, WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare
use AmbassadorHub\Admin\InlineAssets;
use AmbassadorHub\Donations\DonationsModule;
use AmbassadorHub\Fundraisers\Admin\Settings\SettingsManager;
use AmbassadorHub\Fundraisers\FundraisersModule;

use function add_action;
use function wp_add_dashboard_widget;
use function esc_html__;
use function current_user_can;
use function get_posts;
use function esc_html;

/**
 * Registers dashboard widgets for the Fundraiser module.
 */
final class Widgets {
	/**
	 * Initialize widget hooks.
	 *
	 * @return void
	 */
	public static function init(): void {
		add_action( 'ambh_register_dashboard_widgets', array( self::class, 'register_widgets' ) );

		// Inline CSS for the dashboard widget — must be enqueued before
		// admin_print_styles fires, so hooked on load-index.php (the Dashboard
		// screen's load hook) rather than called from the widget render callback.
		add_action( 'load-index.php', array( self::class, 'enqueue_widget_assets' ) );
	}

	/**
	 * Enqueue the inline CSS used by the fundraiser statistics dashboard widget.
	 *
	 * Hooked on 'load-index.php', which fires early enough for
	 * wp_add_inline_style() to still be picked up by admin_print_styles.
	 *
	 * @return void
	 */
	public static function enqueue_widget_assets(): void {
		InlineAssets::style(
			'.fundraiser-stats-widget .stats-grid {
					display: grid;
					grid-template-columns: 1fr 1fr;
					gap: 20px;
					margin-top: 15px;
				}
				.fundraiser-stats-widget .stat-item {
					text-align: center;
					padding: 15px;
					background: #f5f5f5;
					border-radius: 4px;
				}
				.fundraiser-stats-widget .stat-item-link {
					display: block;
					text-decoration: none;
					color: inherit;
					transition: all 0.2s ease;
				}
				.fundraiser-stats-widget .stat-item-link:hover {
					background: #e8e8e8;
					transform: translateY(-2px);
					box-shadow: 0 2px 4px rgba(0,0,0,0.1);
				}
				.fundraiser-stats-widget .stat-number {
					font-size: 32px;
					font-weight: bold;
					color: #0073aa;
					margin-bottom: 5px;
				}
				.fundraiser-stats-widget .stat-label {
					font-size: 13px;
					color: #666;
				}'
		);
	}

	/**
	 * Register dashboard widgets.
	 *
	 * @return void
	 */
	public static function register_widgets(): void {
		if ( ! current_user_can( 'manage_options' ) ) {
			return;
		}

		wp_add_dashboard_widget(
			'ambh_fundraiser_stats',
			esc_html__( 'Fundraiser Statistics', 'ambassadorhub' ),
			array( self::class, 'render_fundraiser_stats' )
		);
	}

	/**
	 * Render the fundraiser statistics widget.
	 *
	 * @return void
	 */
	public static function render_fundraiser_stats(): void {
		// Get total number of campaigns.
		$total_campaigns = self::get_total_campaigns();

		// Get total amount of fundraisers.
		$total_fundraisers = self::get_total_fundraisers();

		// Get donations amount in the past 7 days.
		$recent_donations_amount = self::get_recent_donations_amount( 7 );

		// Get average donation amount in the past 7 days.
		$average_donation_amount = self::get_average_donation_amount( 7 );

		$campaigns_url   = admin_url( 'edit.php?post_type=campaign' );
		$donations_url   = admin_url( 'admin.php?page=ambassador-fundraiser-donations' );
		$fundraisers_url = admin_url( 'edit.php?post_type=fundraiser' );

		?>
		<div class="fundraiser-stats-widget">
			<div class="stats-grid">
				<a href="<?php echo esc_url( $campaigns_url ); ?>" class="stat-item stat-item-link">
					<div class="stat-number"><?php echo esc_html( $total_campaigns ); ?></div>
					<div class="stat-label"><?php esc_html_e( 'Campaigns Created', 'ambassadorhub' ); ?></div>
				</a>
				<a href="<?php echo esc_url( $donations_url ); ?>" class="stat-item stat-item-link">
					<div class="stat-number"><?php echo esc_html( SettingsManager::format_currency( $recent_donations_amount ) ); ?></div>
					<div class="stat-label"><?php esc_html_e( 'Donations Amount (Last 7 Days)', 'ambassadorhub' ); ?></div>
				</a>
				<a href="<?php echo esc_url( $fundraisers_url ); ?>" class="stat-item stat-item-link">
					<div class="stat-number"><?php echo esc_html( $total_fundraisers ); ?></div>
					<div class="stat-label"><?php esc_html_e( 'Fundraisers Created', 'ambassadorhub' ); ?></div>
				</a>
				<div class="stat-item">
					<div class="stat-number"><?php echo esc_html( SettingsManager::format_currency( $average_donation_amount ) ); ?></div>
					<div class="stat-label"><?php esc_html_e( 'Average Donation Amount (Last 7 Days)', 'ambassadorhub' ); ?></div>
				</div>
			</div>
		</div>
		<?php
	}

	private static function get_average_donation_amount( int $days = 7 ): float {
		// Check cache value first
		$cache_key = 'ambh_fundraiser_average_donation_amount_' . $days . 'd';
		$cached    = get_transient( $cache_key );
		if ( false !== $cached ) {
			return (float) $cached;
		}
		global $wpdb;
		$table_name = DonationsModule::get_table_name();
		$days_ago   = gmdate( 'Y-m-d H:i:s', time() - ( $days * DAY_IN_SECONDS ) );
		$average    = $wpdb->get_var(
			$wpdb->prepare(
				"SELECT AVG(amount) FROM $table_name WHERE created_at >= %s AND status = 'completed'",
				$days_ago
			)
		);
		$average    = $average ? (float) $average : 0.0;
		// Cache for 15 minutes.
		set_transient( $cache_key, $average, 1 * HOUR_IN_SECONDS );
		return $average;
	}

	private static function get_total_fundraisers(): int {
		$cache_key = 'ambh_fundraiser_total_fundraisers';
		$cached    = get_transient( $cache_key );

		if ( false !== $cached ) {
			return (int) $cached;
		}

		$fundraisers = get_posts(
			array(
				'post_type'      => FundraisersModule::POST_TYPE,
				'post_status'    => 'publish',
				'posts_per_page' => -1,
				'fields'         => 'ids',
			)
		);

		$count = count( $fundraisers );

		// Cache for 15 minutes.
		set_transient( $cache_key, $count, 15 * MINUTE_IN_SECONDS );

		return $count;
	}

	/**
	 * Get the total number of campaigns.
	 *
	 * @return int Total campaign count.
	 */
	private static function get_total_campaigns(): int {

		// Check cache values first
		$cache_key = 'ambh_fundraiser_total_campaigns';
		$cached    = get_transient( $cache_key );

		if ( false !== $cached ) {
				return (int) $cached;
		}

		$campaigns = get_posts(
			array(
				'post_type'      => 'campaign',
				'post_status'    => 'publish',
				'posts_per_page' => -1,
				'fields'         => 'ids',
			)
		);

		$count = count( $campaigns );

		// Cache value for 15 minutes.
		set_transient( $cache_key, $count, 15 * MINUTE_IN_SECONDS );

		return $count;
	}

	/**
	 * Get the total amount of donations in the past N days.
	 *
	 * @param int $days Number of days to look back.
	 *
	 * @return float Total donation amount.
	 */
	private static function get_recent_donations_amount( int $days = 7 ): float {
		$cache_key = 'ambh_fundraiser_recent_donations_amount_' . $days . 'd';
		$cached    = get_transient( $cache_key );

		// Check cache value first

		if ( false !== $cached ) {
			return (float) $cached;
		}

		global $wpdb;
		$table_name = DonationsModule::get_table_name();
		$days_ago   = gmdate( 'Y-m-d H:i:s', time() - ( $days * DAY_IN_SECONDS ) );

		$amount = $wpdb->get_var(
			$wpdb->prepare(
				"SELECT COALESCE(SUM(amount), 0) FROM $table_name WHERE created_at >= %s AND status = 'completed'",
				$days_ago
			)
		);

		$amount = $amount ? (float) $amount : 0.0;

		// Cache for 15 minutes.
		set_transient( $cache_key, $amount, 15 * MINUTE_IN_SECONDS );

		return $amount;
	}
}
