<?php

declare(strict_types=1);

namespace Australcode\Rewards\Admin;

use Australcode\Rewards\Service\Licensing\LicenseGate;

defined( 'ABSPATH' ) || exit;

/**
 * "Help" page — the in-admin integration reference.
 *
 * The plugin ships a full set of customer-facing shortcodes + Gutenberg blocks, a
 * REST API and developer hooks, but until now none of them were discoverable from
 * the admin — a merchant had to read readme.txt or the block inserter to learn the
 * surfaces existed (code-vs-UI audit, 2026-06-25). This page closes that gap: a
 * read-only reference with three stacked sections (shortcodes & blocks, REST API,
 * developer hooks).
 *
 * Core / both builds. The catalogs are STATIC DATA (no reflection over the Pro
 * classes), so the free WP.org build documents the Pro shortcodes/endpoints with a
 * "Pro" badge without referencing the @fs_premium_only classes it stripped — the
 * same transparency-freemium stance as the Tiers/Campaigns upsell. No JS, no remote
 * calls: zero compliance surface.
 */
final class HelpPage {

	use RendersPageHeader;

	private const CAPABILITY = 'manage_woocommerce';

	public function __construct( private readonly LicenseGate $gate ) {}

	/**
	 * Customer-facing shortcodes and their Gutenberg block duals. Public + static so
	 * the anti-drift test can assert it matches the shortcodes actually registered by
	 * Shortcodes / ProShortcodes (the catalog can never silently go stale).
	 *
	 * @return array<int,array{tag:string,desc:string,atts:string,block:string,pro:bool}>
	 */
	public static function shortcode_catalog(): array {
		return array(
			array(
				'tag'   => 'acrwd_balance',
				'desc'  => __( 'The logged-in customer’s current points balance.', 'australcode-points-rewards' ),
				'atts'  => 'label, class',
				'block' => __( 'Points Balance', 'australcode-points-rewards' ),
				'pro'   => false,
			),
			array(
				'tag'   => 'acrwd_history',
				'desc'  => __( 'A table of the customer’s recent points activity.', 'australcode-points-rewards' ),
				'atts'  => 'limit, class',
				'block' => __( 'Points History', 'australcode-points-rewards' ),
				'pro'   => false,
			),
			array(
				'tag'   => 'acrwd_earn_message',
				'desc'  => __( '“Earn X points with this purchase” for a product.', 'australcode-points-rewards' ),
				'atts'  => 'product_id, class',
				'block' => __( 'Earn Points Message', 'australcode-points-rewards' ),
				'pro'   => false,
			),
			array(
				'tag'   => 'acrwd_redeem',
				'desc'  => __( 'The “use your points” redeem form for the current cart.', 'australcode-points-rewards' ),
				'atts'  => '—',
				'block' => __( 'Redeem Points', 'australcode-points-rewards' ),
				'pro'   => false,
			),
			array(
				'tag'   => 'acrwd_tier',
				'desc'  => __( 'The customer’s current VIP tier and earning multiplier.', 'australcode-points-rewards' ),
				'atts'  => '—',
				'block' => __( 'VIP Tier', 'australcode-points-rewards' ),
				'pro'   => true,
			),
			array(
				'tag'   => 'acrwd_referral',
				'desc'  => __( 'The customer’s referral link and successful-referral count.', 'australcode-points-rewards' ),
				'atts'  => '—',
				'block' => __( 'Referral Link', 'australcode-points-rewards' ),
				'pro'   => true,
			),
		);
	}

	/**
	 * REST endpoints under the acrwd/v1 namespace.
	 *
	 * @return array<int,array{method:string,route:string,access:string,desc:string,pro:bool}>
	 */
	private function rest_catalog(): array {
		$logged_in = __( 'Logged-in customer', 'australcode-points-rewards' );
		$admin     = __( 'Shop manager', 'australcode-points-rewards' );

		return array(
			array(
				'method' => 'GET',
				'route'  => '/wallet/balance',
				'access' => $logged_in,
				'desc'   => __( 'The current customer’s balance and lifetime totals.', 'australcode-points-rewards' ),
				'pro'    => false,
			),
			array(
				'method' => 'GET',
				'route'  => '/wallet/transactions',
				'access' => $logged_in,
				'desc'   => __( 'The current customer’s ledger (params: limit, offset).', 'australcode-points-rewards' ),
				'pro'    => false,
			),
			array(
				'method' => 'POST',
				'route'  => '/wallet/adjust',
				'access' => $admin,
				'desc'   => __( 'Manually credit or debit a customer (params: user_id, points, reason).', 'australcode-points-rewards' ),
				'pro'    => false,
			),
			array(
				'method' => 'GET',
				'route'  => '/redemption/quote',
				'access' => $logged_in,
				'desc'   => __( 'Preview the discount for a points amount — no side effects (param: points).', 'australcode-points-rewards' ),
				'pro'    => false,
			),
			array(
				'method' => 'POST',
				'route'  => '/redemption/apply',
				'access' => $logged_in,
				'desc'   => __( 'Store the chosen points on the current cart session (param: points).', 'australcode-points-rewards' ),
				'pro'    => false,
			),
			array(
				'method' => 'POST',
				'route'  => '/redemption/clear',
				'access' => $logged_in,
				'desc'   => __( 'Remove the redemption from the cart session.', 'australcode-points-rewards' ),
				'pro'    => false,
			),
			array(
				'method' => 'GET',
				'route'  => '/tiers',
				'access' => $admin,
				'desc'   => __( 'List VIP tiers.', 'australcode-points-rewards' ),
				'pro'    => true,
			),
			array(
				'method' => 'POST',
				'route'  => '/tiers',
				'access' => $admin,
				'desc'   => __( 'Create a VIP tier (params: name, threshold_points, multiplier, sort_order).', 'australcode-points-rewards' ),
				'pro'    => true,
			),
			array(
				'method' => 'DELETE',
				'route'  => '/tiers/{id}',
				'access' => $admin,
				'desc'   => __( 'Delete a VIP tier.', 'australcode-points-rewards' ),
				'pro'    => true,
			),
			array(
				'method' => 'GET',
				'route'  => '/tiers/me',
				'access' => $logged_in,
				'desc'   => __( 'The current customer’s tier.', 'australcode-points-rewards' ),
				'pro'    => true,
			),
			array(
				'method' => 'GET',
				'route'  => '/campaigns',
				'access' => $admin,
				'desc'   => __( 'List campaigns.', 'australcode-points-rewards' ),
				'pro'    => true,
			),
			array(
				'method' => 'POST',
				'route'  => '/campaigns',
				'access' => $admin,
				'desc'   => __( 'Create a campaign (params: name, multiplier, starts_at, ends_at, active).', 'australcode-points-rewards' ),
				'pro'    => true,
			),
			array(
				'method' => 'DELETE',
				'route'  => '/campaigns/{id}',
				'access' => $admin,
				'desc'   => __( 'Delete a campaign.', 'australcode-points-rewards' ),
				'pro'    => true,
			),
		);
	}

	/**
	 * Public developer hooks (extension points). Internal/defense hooks
	 * (e.g. acrwd_pro_forced_values) are intentionally omitted.
	 *
	 * @return array<int,array{hook:string,type:string,signature:string,desc:string}>
	 */
	private function hooks_catalog(): array {
		return array(
			array(
				'hook'      => 'acrwd_earning_multiplier',
				'type'      => 'filter',
				'signature' => '( int $points, int $user_id, WC_Order $order )',
				'desc'      => __( 'Stack an extra earning multiplier on top of the base + per-role amount. The Pro tier (10) and campaign (20) services already hook this.', 'australcode-points-rewards' ),
			),
			array(
				'hook'      => 'acrwd_role_earning_multiplier',
				'type'      => 'filter',
				'signature' => '( float $multiplier, int $user_id, string[] $roles )',
				'desc'      => __( 'Customise the per-role earning multiplier for a customer.', 'australcode-points-rewards' ),
			),
			array(
				'hook'      => 'acrwd_order_earned_points',
				'type'      => 'filter',
				'signature' => '( int $fallback, WC_Order $order )',
				'desc'      => __( 'Read the points an order earned (ledger amount once awarded, otherwise a preview) — e.g. to show the figure on the thank-you page.', 'australcode-points-rewards' ),
			),
			array(
				'hook'      => 'acrwd_account_endpoint',
				'type'      => 'filter',
				'signature' => '( string $endpoint )',
				'desc'      => __( 'Change the My Account “Rewards” endpoint slug (default "rewards").', 'australcode-points-rewards' ),
			),
			array(
				'hook'      => 'acrwd_enqueue_frontend',
				'type'      => 'filter',
				'signature' => '( bool $should )',
				'desc'      => __( 'Force-load the storefront CSS where the plugin cannot detect it automatically (some page builders).', 'australcode-points-rewards' ),
			),
			array(
				'hook'      => 'acrwd_points_earned',
				'type'      => 'action',
				'signature' => '( int $user_id, WC_Order $order )',
				'desc'      => __( 'Fires after an order’s points are awarded — react with a webhook, notification, etc.', 'australcode-points-rewards' ),
			),
			array(
				'hook'      => 'acrwd_tier_changed',
				'type'      => 'action',
				'signature' => '( int $user_id, ?Tier $tier )',
				'desc'      => __( 'Fires when a customer’s VIP tier changes (Pro) — e.g. sync the tier to a CRM. $tier is null when they drop below the lowest tier.', 'australcode-points-rewards' ),
			),
		);
	}

	public function render(): void {
		if ( ! current_user_can( self::CAPABILITY ) ) {
			wp_die( esc_html__( 'You are not allowed to access this page.', 'australcode-points-rewards' ) );
		}

		echo '<div class="wrap acds-root acrwd-page"><div class="acds-wrap">';
		$this->render_page_header(
			__( 'Help', 'australcode-points-rewards' ),
			__( 'Shortcodes, blocks, the REST API and developer hooks — everything to place and extend your rewards program.', 'australcode-points-rewards' ),
			$this->dashboard_back_action()
		);

		$this->render_shortcodes_section();
		$this->render_rest_section();
		$this->render_hooks_section();

		echo '</div></div>';
	}

	private function render_shortcodes_section(): void {
		echo '<div class="acds-surface"><div class="acds-surface__head"><h2 class="acds-surface__title">'
			. esc_html__( 'Shortcodes & blocks', 'australcode-points-rewards' ) . '</h2>'
			. '<span class="acrwd-surface-meta">' . esc_html__( 'place rewards surfaces anywhere', 'australcode-points-rewards' ) . '</span></div>';
		echo '<div class="acds-surface__body">';
		echo '<p class="acds-muted">' . esc_html__( 'Drop a shortcode into any page, post, widget or page-builder block. Each one is also a Gutenberg block — search “Australcode” or “points” in the block inserter. Customer-facing surfaces render nothing for logged-out visitors.', 'australcode-points-rewards' ) . '</p>';

		echo '<table class="wp-list-table widefat striped acrwd-table-cards acrwd-ref-table"><thead><tr>';
		echo '<th>' . esc_html__( 'Shortcode', 'australcode-points-rewards' ) . '</th>';
		echo '<th>' . esc_html__( 'What it shows', 'australcode-points-rewards' ) . '</th>';
		echo '<th>' . esc_html__( 'Attributes', 'australcode-points-rewards' ) . '</th>';
		echo '<th>' . esc_html__( 'Block', 'australcode-points-rewards' ) . '</th>';
		echo '</tr></thead><tbody>';

		foreach ( self::shortcode_catalog() as $row ) {
			echo '<tr>';
			echo '<td data-label="' . esc_attr__( 'Shortcode', 'australcode-points-rewards' ) . '"><code class="acrwd-code">[' . esc_html( $row['tag'] ) . ']</code>' . wp_kses_post( $this->pro_badge( $row['pro'] ) ) . '</td>';
			echo '<td data-label="' . esc_attr__( 'What it shows', 'australcode-points-rewards' ) . '">' . esc_html( $row['desc'] ) . '</td>';
			echo '<td data-label="' . esc_attr__( 'Attributes', 'australcode-points-rewards' ) . '"><code class="acrwd-code">' . esc_html( $row['atts'] ) . '</code></td>';
			echo '<td data-label="' . esc_attr__( 'Block', 'australcode-points-rewards' ) . '">' . esc_html( $row['block'] ) . '</td>';
			echo '</tr>';
		}

		echo '</tbody></table>';
		if ( ! $this->gate->is_pro_active() ) {
			echo '<p class="acds-muted">' . esc_html__( 'Shortcodes marked Pro render only with an active Pro license.', 'australcode-points-rewards' ) . '</p>';
		}
		echo '</div></div>';
	}

	private function render_rest_section(): void {
		echo '<div class="acds-surface"><div class="acds-surface__head"><h2 class="acds-surface__title">'
			. esc_html__( 'REST API', 'australcode-points-rewards' ) . '</h2>'
			. '<span class="acrwd-surface-meta">' . esc_html__( 'integrate programmatically', 'australcode-points-rewards' ) . '</span></div>';
		echo '<div class="acds-surface__body">';
		echo '<p class="acds-muted">' . sprintf(
			/* translators: %s: the REST API base URL. */
			esc_html__( 'Base URL: %s. Authenticate with the logged-in cookie + nonce, or with an Application Password for server-to-server calls.', 'australcode-points-rewards' ),
			'<code class="acrwd-code">' . esc_url( rest_url( 'acrwd/v1' ) ) . '</code>'
		) . '</p>';

		echo '<table class="wp-list-table widefat striped acrwd-table-cards acrwd-ref-table"><thead><tr>';
		echo '<th>' . esc_html__( 'Method', 'australcode-points-rewards' ) . '</th>';
		echo '<th>' . esc_html__( 'Endpoint', 'australcode-points-rewards' ) . '</th>';
		echo '<th>' . esc_html__( 'Access', 'australcode-points-rewards' ) . '</th>';
		echo '<th>' . esc_html__( 'Purpose', 'australcode-points-rewards' ) . '</th>';
		echo '</tr></thead><tbody>';

		foreach ( $this->rest_catalog() as $row ) {
			echo '<tr>';
			echo '<td data-label="' . esc_attr__( 'Method', 'australcode-points-rewards' ) . '"><code class="acrwd-code">' . esc_html( $row['method'] ) . '</code></td>';
			echo '<td data-label="' . esc_attr__( 'Endpoint', 'australcode-points-rewards' ) . '"><code class="acrwd-code">' . esc_html( $row['route'] ) . '</code>' . wp_kses_post( $this->pro_badge( $row['pro'] ) ) . '</td>';
			echo '<td data-label="' . esc_attr__( 'Access', 'australcode-points-rewards' ) . '">' . esc_html( $row['access'] ) . '</td>';
			echo '<td data-label="' . esc_attr__( 'Purpose', 'australcode-points-rewards' ) . '">' . esc_html( $row['desc'] ) . '</td>';
			echo '</tr>';
		}

		echo '</tbody></table></div></div>';
	}

	private function render_hooks_section(): void {
		echo '<div class="acds-surface"><div class="acds-surface__head"><h2 class="acds-surface__title">'
			. esc_html__( 'Developer hooks', 'australcode-points-rewards' ) . '</h2>'
			. '<span class="acrwd-surface-meta">' . esc_html__( 'extend with code', 'australcode-points-rewards' ) . '</span></div>';
		echo '<div class="acds-surface__body">';
		echo '<p class="acds-muted">' . esc_html__( 'Actions and filters for extending the rewards engine from a theme or companion plugin.', 'australcode-points-rewards' ) . '</p>';

		echo '<table class="wp-list-table widefat striped acrwd-table-cards acrwd-ref-table"><thead><tr>';
		echo '<th>' . esc_html__( 'Hook', 'australcode-points-rewards' ) . '</th>';
		echo '<th>' . esc_html__( 'Type', 'australcode-points-rewards' ) . '</th>';
		echo '<th>' . esc_html__( 'Signature', 'australcode-points-rewards' ) . '</th>';
		echo '<th>' . esc_html__( 'Purpose', 'australcode-points-rewards' ) . '</th>';
		echo '</tr></thead><tbody>';

		foreach ( $this->hooks_catalog() as $row ) {
			echo '<tr>';
			echo '<td data-label="' . esc_attr__( 'Hook', 'australcode-points-rewards' ) . '"><code class="acrwd-code">' . esc_html( $row['hook'] ) . '</code></td>';
			echo '<td data-label="' . esc_attr__( 'Type', 'australcode-points-rewards' ) . '">' . esc_html( $row['type'] ) . '</td>';
			echo '<td data-label="' . esc_attr__( 'Signature', 'australcode-points-rewards' ) . '"><code class="acrwd-code">' . esc_html( $row['signature'] ) . '</code></td>';
			echo '<td data-label="' . esc_attr__( 'Purpose', 'australcode-points-rewards' ) . '">' . esc_html( $row['desc'] ) . '</td>';
			echo '</tr>';
		}

		echo '</tbody></table></div></div>';
	}

	/** Pre-escaped "Pro" badge markup, or '' for Free rows. */
	private function pro_badge( bool $pro ): string {
		return $pro
			? ' <span class="acds-badge acds-badge--pro">' . esc_html__( 'Pro', 'australcode-points-rewards' ) . '</span>'
			: '';
	}
}
