<?php
/**
 * The analytics screen.
 *
 * @package TextTango
 */

declare( strict_types=1 );

namespace TextTango\Admin;

use TextTango\Analytics\Stats;
use TextTango\Install\Activator;

defined( 'ABSPATH' ) || exit;

/**
 * What this site has been sending, on a screen of its own (spec §11).
 *
 * ### Why this is not a settings tab
 *
 * It began as a card above the message log, on Settings → Logs. Everything else
 * under Settings *configures* what the plugin does; this *reports* on it, and
 * the two do not belong on one screen. Reaching a report meant scrolling past
 * the balance cards and a nine-tab strip to find it sitting above an unrelated
 * table — and every visit to the log, which is a different job, paid for the
 * aggregates behind it.
 *
 * A tab was the other option and was rejected: the strip already carries nine.
 *
 * ### There is no state here
 *
 * Nothing on this screen is saved, so it has no form, no nonce and no
 * `admin_post` handler. The one thing a merchant can change is the window, and
 * that travels as a query argument {@see Stats::window_from_request()} validates
 * against a fixed list — which is why this class registers no hooks at all and
 * {@see Menu} simply calls `render()`.
 */
final class AnalyticsPage {

	/**
	 * Slug of the screen.
	 */
	public const SLUG = 'texttango-analytics';

	/**
	 * A link to this screen.
	 *
	 * @param int $days Window to open on, or 0 for the default.
	 */
	public static function url( int $days = 0 ): string {
		$args = array( 'page' => self::SLUG );

		// Only when it is one of the offered windows. A link carrying anything
		// else would put an argument in the address bar that the screen then
		// silently ignores, which reads as the page having lost the setting.
		if ( in_array( $days, Stats::WINDOWS, true ) ) {
			$args[ Stats::ARG ] = (string) $days;
		}

		return add_query_arg( $args, admin_url( 'admin.php' ) );
	}

	/**
	 * The window links, one per offered period.
	 *
	 * @return array<string, string>
	 */
	public static function windows(): array {
		$windows = array();

		foreach ( Stats::WINDOWS as $window ) {
			$windows[ (string) $window ] = self::url( $window );
		}

		return $windows;
	}

	/**
	 * Draw the screen.
	 */
	public function render(): void {
		if ( ! current_user_can( Activator::CAPABILITY ) ) {
			wp_die( esc_html__( 'You do not have permission to view TextTango analytics.', 'texttango' ) );
		}

		// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only view state; Stats validates it against a fixed list of windows.
		$days = Stats::window_from_request( wp_unslash( $_GET ) );

		load_template(
			TEXTTANGO_PATH . 'templates/admin/analytics.php',
			false,
			array(
				/*
				 * Live, not cached. This screen is opened deliberately and rarely,
				 * and an uncached read is eight queries — against figures that were
				 * otherwise up to five minutes old, so a campaign just sent was not
				 * on the screen the merchant opened to look for it.
				 */
				'stats'       => Stats::summary( $days, false ),
				'tones'       => Stats::tones(),
				'windows'     => self::windows(),
				'log_url'     => Tabs::url( Tabs::LOGS ),
				'history_url' => CampaignsPage::url( CampaignsPage::VIEW_HISTORY ),
				'currency'    => (string) get_option( 'woocommerce_currency', '' ),
			)
		);
	}
}
