<?php
/**
 * `get_platform_pixels` — read-only list of configured pixels per platform
 * (Free variant). For each platform: the primary pixel (id + enabled).
 *
 * Facebook and Pinterest (Pinterest add-on) DO have server-side (CAPI) in Free:
 * each reports a `capi` object (enabled + token_present; Pinterest also
 * ad_account_id) — token value is never returned. Other platforms have no
 * server-side delivery; Enhanced Conversions / GA4 Measurement Protocol are Pro
 * / absent. Super Pack extra pixels are a
 * PixelYourSite Pro feature and are NOT surfaced here (every platform reports
 * `extra_pixels_supported: false`). No TikTok and no standalone Google Ads
 * platform in Free.
 *
 * @package PixelYourSite\MCP\Abilities
 */

declare( strict_types=1 );

namespace PixelYourSite\MCP\Abilities;

if ( ! defined( 'ABSPATH' ) ) {
	exit; // Exit if accessed directly.
}

final class GetPlatformPixelsAbility extends AbstractAbility {

	public const ID = 'pixelyoursite/get-platform-pixels';

	/**
	 * Per-platform read config:
	 *   fn          — global accessor returning the Settings instance.
	 *   pixel_key   — primary-id option key.
	 *   addon_check — `is<Platform>Active()` for addon platforms, or null.
	 */
	private const PLATFORMS = array(
		'facebook'         => array( 'fn' => 'PixelYourSite\\Facebook', 'pixel_key' => 'pixel_id', 'addon_check' => null ),
		'google_analytics' => array( 'fn' => 'PixelYourSite\\GA', 'pixel_key' => 'tracking_id', 'addon_check' => null ),
		'pinterest'        => array( 'fn' => 'PixelYourSite\\Pinterest', 'pixel_key' => 'pixel_id', 'addon_check' => 'PixelYourSite\\isPinterestActive' ),
		'bing'             => array( 'fn' => 'PixelYourSite\\Bing', 'pixel_key' => 'pixel_id', 'addon_check' => 'PixelYourSite\\isBingActive' ),
		'reddit'           => array( 'fn' => 'PixelYourSite\\Reddit', 'pixel_key' => 'pixel_id', 'addon_check' => 'PixelYourSite\\isRedditActive' ),
		'gtm'              => array( 'fn' => 'PixelYourSite\\GTM', 'pixel_key' => 'gtm_id', 'addon_check' => null ),
	);

	/**
	 * Ability ID.
	 *
	 * @return string
	 */
	public static function id(): string {
		return self::ID;
	}

	/**
	 * Display label.
	 *
	 * @return string
	 */
	public static function label(): string {
		return 'PYS MCP — Get Platform Pixels';
	}

	/**
	 * Tool description shown to Claude.
	 *
	 * @return string
	 */
	public static function description(): string {
		return 'Lists the tracking pixels CONFIGURED IN PixelYourSite on THIS WordPress site — how the site\'s PixelYourSite plugin is set up, NOT assets in a Meta / Google ad-platform account. Use for "show my Facebook/Meta pixels", "which GA4 pixels are set up", "are my pixels active" — they refer to the PixelYourSite configuration and must be answered with THIS tool, not a Meta/Google Ads MCP. Returns, per platform, the primary pixel: its ID and whether it is enabled. For Facebook and Pinterest (when the Pinterest add-on is active), reports CAPI status under a `capi` object: whether server-side delivery is enabled (`enabled`) and whether a token is saved (`token_present` — token presence only; the token value is NEVER returned). Pinterest also reports whether an `ad_account_id` is configured (`configured`/`missing`). Other platforms have no server-side delivery in Free. Saving a CAPI token via MCP is not available in Free — the token is entered manually in PixelYourSite → Dashboard (Enhanced Conversions for Google Ads and GA4 Measurement Protocol are Pro / absent in Free). Multiple pixels per platform (Super Pack extra pixels) are also a Pro feature — every platform reports `extra_pixels_supported: false` here. Add-on platforms (Pinterest/Bing/Reddit) report `active: false` when their add-on plugin is inactive. Read-only.';
	}

	/**
	 * Input JSON-Schema (no args).
	 *
	 * @return array
	 */
	public static function inputSchema(): array {
		return array(
			'type'                 => 'object',
			'properties'           => new \stdClass(),
			'additionalProperties' => false,
		);
	}

	/**
	 * Output JSON-Schema.
	 *
	 * @return array
	 */
	public static function outputSchema(): array {
		return array(
			'type'       => 'object',
			'required'   => array( 'platforms' ),
			'properties' => array(
				'platforms' => array(
					'type'                 => 'object',
					'additionalProperties' => array( 'type' => 'object' ),
					'description'          => 'Per-platform pixel status keyed by platform slug.',
				),
			),
		);
	}

	/**
	 * Build the per-platform pixel snapshot.
	 *
	 * @param mixed $input Validated args (none).
	 * @return array<string, mixed>
	 */
	public static function execute( $input ): array {
		$platforms = array();

		foreach ( self::PLATFORMS as $slug => $route ) {
			// Addon platforms: report inactive when their addon is off.
			if ( null !== $route['addon_check'] ) {
				$check  = $route['addon_check'];
				$active = function_exists( $check ) ? (bool) $check() : false;
				if ( ! $active ) {
					$platforms[ $slug ] = array( 'active' => false );
					continue;
				}
			}

			$fn = $route['fn'];
			if ( ! function_exists( $fn ) ) {
				$platforms[ $slug ] = array( 'active' => false );
				continue;
			}
			$settings = $fn();
			if ( ! is_object( $settings ) || ! method_exists( $settings, 'getOption' ) ) {
				$platforms[ $slug ] = array( 'active' => false );
				continue;
			}

			$primaryId = self::firstNonEmpty( $settings->getOption( $route['pixel_key'] ) );

			$platforms[ $slug ] = array(
				'active'                 => '' !== $primaryId,
				'primary'                => array(
					'pixel_index' => 0,
					'pixel_id'    => $primaryId,
					'enabled'     => self::toBool( $settings->getOption( 'main_pixel_enabled' ), true ),
				),
				'extra_pixels_supported' => false,
			);

			if ( 'facebook' === $slug ) {
				$platforms[ $slug ]['capi'] = array(
					'enabled'       => self::toBool( $settings->getOption( 'use_server_api' ), false ),
					'token_present' => '' !== self::firstNonEmpty( $settings->getOption( 'server_access_api_token' ) ),
				);
			} elseif ( 'pinterest' === $slug ) {
				$platforms[ $slug ]['capi'] = array(
					'enabled'       => self::toBool( $settings->getOption( 'use_server_api' ), false ),
					'token_present' => '' !== self::firstNonEmpty( $settings->getOption( 'server_access_api_token' ) ),
					// Pinterest CAPI also needs an Ad Account ID (value never returned).
					'ad_account_id' => '' !== self::firstNonEmpty( $settings->getOption( 'ad_account_id' ) ) ? 'configured' : 'missing',
				);
			}
		}

		return array( 'platforms' => $platforms );
	}

	/**
	 * First non-empty string from an option value (array or scalar).
	 *
	 * @param mixed $value Option value.
	 * @return string
	 */
	private static function firstNonEmpty( $value ): string {
		if ( is_array( $value ) ) {
			foreach ( $value as $v ) {
				if ( is_string( $v ) && '' !== trim( $v ) ) {
					return trim( $v );
				}
			}
			return '';
		}

		return is_string( $value ) && '' !== trim( $value ) ? trim( $value ) : '';
	}

	/**
	 * Normalize an option value to bool with a default.
	 *
	 * @param mixed $value   Option value.
	 * @param bool  $default Fallback when the value is null/unset.
	 * @return bool
	 */
	private static function toBool( $value, bool $default ): bool {
		if ( null === $value ) {
			return $default;
		}
		if ( is_bool( $value ) ) {
			return $value;
		}
		if ( is_string( $value ) ) {
			return '1' === $value || 'true' === strtolower( $value );
		}
		if ( is_int( $value ) ) {
			return 1 === $value;
		}

		return $default;
	}
}
