<?php
/**
 * WooCommerce provider-owned target authorization.
 *
 * @package ScheduledChangesWooCommerce
 */

namespace ScheduledChangesWooCommerce\CoreCompat\WooCommerce;

use ScheduledChanges\Domain\Operation\TargetDefinition;

/**
 * Maps WooCommerce-owned provider targets to WordPress product capabilities.
 */
final class WooCommerceProviderAuthorization {
	/**
	 * Provider IDs whose targets are owned by WooCommerce product posts.
	 *
	 * @var string[]
	 */
	private const PRODUCT_SCOPED_PROVIDERS = array(
		'woocommerce-core',
		'product-taxonomies',
	);

	/**
	 * Registers the extension authorization policy.
	 */
	public function register(): void {
		add_filter( 'scheduled_changes_provider_authorization', array( $this, 'authorize' ), 10, 4 );
	}

	/**
	 * Authorizes a product-scoped WooCommerce provider target.
	 */
	public function authorize( bool $authorized, string $action, int $actor_id, TargetDefinition $target ): bool {
		if ( ! in_array( $target->providerId(), self::PRODUCT_SCOPED_PROVIDERS, true ) ) {
			return $authorized;
		}

		$target_id = $this->targetProductId( $target );

		if ( $target_id <= 0 || ! get_userdata( $actor_id ) instanceof \WP_User ) {
			return false;
		}

		if ( 'inspect' === $action ) {
			return user_can( $actor_id, 'read_post', $target_id );
		}

		if ( in_array( $action, array( 'schedule', 'execute', 'rollback', 'delete' ), true ) ) {
			return user_can( $actor_id, 'edit_post', $target_id );
		}

		return false;
	}

	/**
	 * Resolves the owning product ID for an existing or future provider target.
	 */
	private function targetProductId( TargetDefinition $target ): int {
		$target_id = null === $target->targetId() ? 0 : $target->targetId();

		if ( $target_id > 0 && ! wc_get_product( $target_id ) instanceof \WC_Product ) {
			$target_id = 0;
		}

		if ( $target_id <= 0 && null !== $target->parentReference() ) {
			$target_id = $this->productIdFromReference( $target->parentReference() );
		}

		if ( $target_id <= 0 ) {
			$target_id = $this->productIdFromReference( $target->reference() );
		}

		return $target_id;
	}

	/**
	 * Resolves a WooCommerce product ID from legacy CLI input or target reference.
	 */
	private function productIdFromReference( string $target_reference ): int {
		$target_reference = trim( $target_reference );

		if ( ctype_digit( $target_reference ) ) {
			return (int) $target_reference;
		}

		if ( preg_match( '/^(?:product|variation):(\d+)$/', $target_reference, $matches ) ) {
			return (int) $matches[1];
		}

		return 0;
	}
}
