<?php
/**
 * Metadata ownership heuristics.
 *
 * @package ScheduledChanges
 */

namespace ScheduledChanges\Discovery;

use Closure;

/**
 * Reports likely ownership without pretending heuristics are definitive.
 */
final class MetadataOwnerDetector {
	/**
	 * @param array<string,mixed>|null $registration Registered metadata schema.
	 */
	public function detect( string $key, ?array $registration = null ): string {
		if ( null !== $registration ) {
			$callbacks = array(
				$registration['sanitize_callback'] ?? null,
				$registration['auth_callback'] ?? null,
			);

			foreach ( $callbacks as $callback ) {
				$owner = $this->callbackOwner( $callback );

				if ( '' !== $owner && 'WordPress callback' !== $owner ) {
					return $owner;
				}
			}

			return 'Registered integration';
		}

		$prefixes = array(
			'_scheduled_changes_' => 'Scheduled Changes',
			'_wc_'                => 'WooCommerce',
			'_woocommerce_'       => 'WooCommerce',
			'_product_'           => 'WooCommerce',
			'_price'              => 'WooCommerce',
			'_regular_price'      => 'WooCommerce',
			'_sale_price'         => 'WooCommerce',
			'_stock'              => 'WooCommerce',
			'_sku'                => 'WooCommerce',
			'_download'           => 'WooCommerce',
			'_virtual'            => 'WooCommerce',
			'_yoast_wpseo_'       => 'Yoast SEO',
			'rank_math_'          => 'Rank Math',
			'_acf'                => 'Advanced Custom Fields',
			'_wp_'                => 'WordPress',
		);

		foreach ( $prefixes as $prefix => $owner ) {
			if ( strncmp( $key, $prefix, strlen( $prefix ) ) === 0 ) {
				return $owner;
			}
		}

		return 'Unknown';
	}

	/**
	 * @param mixed $callback
	 */
	public function callbackDescription( $callback ): string {
		if ( is_string( $callback ) ) {
			return $callback;
		}

		if ( $callback instanceof Closure ) {
			return 'closure';
		}

		if ( is_array( $callback ) && 2 === count( $callback ) ) {
			$target = is_object( $callback[0] )
				? get_class( $callback[0] )
				: (string) $callback[0];

			return $target . '::' . (string) $callback[1];
		}

		if ( is_object( $callback ) && is_callable( $callback ) ) {
			return get_class( $callback ) . '::__invoke';
		}

		return '';
	}

	/**
	 * @param mixed $callback
	 */
	private function callbackOwner( $callback ): string {
		$description = $this->callbackDescription( $callback );

		if ( '' === $description ) {
			return '';
		}

		if ( strncmp( $description, 'Automattic\\WooCommerce', strlen( 'Automattic\\WooCommerce' ) ) === 0 || strncmp( $description, 'WC_', strlen( 'WC_' ) ) === 0 ) {
			return 'WooCommerce';
		}

		if ( strncmp( $description, 'ScheduledChanges\\', strlen( 'ScheduledChanges\\' ) ) === 0 ) {
			return 'Scheduled Changes';
		}

		if ( strpos( $description, '\\' ) === false && strpos( $description, '::' ) === false ) {
			return 'WordPress callback';
		}

		$parts = preg_split( '/[\\\\:]/', $description );

		return is_array( $parts ) && '' !== (string) ( $parts[0] ?? '' )
			? (string) $parts[0]
			: 'Registered integration';
	}
}
