<?php
namespace WebshoptigerCatalogSync;

defined( 'ABSPATH' ) || exit;

/**
 * DestinationGuard
 *
 * Protects products on the destination site that were NOT created via Webshoptiger Catalog Sync.
 *
 * Every product that Webshoptiger Catalog Sync creates gets a 'supplier' meta field with the
 * supplier ID of the source site (see Settings::supplier_id()). Products
 * without this field are always "own" products of the destination site
 * administrator and are never overwritten or deleted by synchronization.
 *
 * Works in two ways:
 *
 * 1. WITH the plugin on the destination site: hooks into the WooCommerce
 *    REST API and blocks updates/deletes of products without valid
 *    supplier meta directly on the destination site.
 *
 * 2. WITHOUT the plugin on the destination site: the source site checks
 *    before an update whether the remote product has a valid supplier
 *    field via a GET request to the WooCommerce REST API.
 */
class DestinationGuard {

    const META_KEY = 'supplier';

    // -------------------------------------------------------------------------
    // Hooks for when the plugin IS installed on the destination site
    // -------------------------------------------------------------------------

    public static function init(): void {
        add_filter( 'woocommerce_rest_pre_insert_product_object', [ __CLASS__, 'guard_update' ], 10, 3 );
        add_action( 'woocommerce_rest_delete_product',            [ __CLASS__, 'guard_delete' ], 10, 3 );
    }

    public static function guard_update( \WC_Product $product, \WP_REST_Request $request, bool $creating ): mixed {
        if ( $creating ) {
            return $product; // Creating is always allowed
        }

        if ( ! self::is_synced_product( $product->get_id() ) ) {
            return new \WP_Error(
                'webshoptigercatalogsync_protected',
                'This product was not created by ' . WEBSHOPTIGERCATALOGSYNC_PLUGIN_NAME . ' and cannot be modified via synchronization.',
                [ 'status' => 403 ]
            );
        }

        return $product;
    }

    public static function guard_delete( \WP_Post $post, $response, \WP_REST_Request $request ): void {
        if ( ! self::is_synced_product( $post->ID ) ) {
            if ( defined('WP_DEBUG') && WP_DEBUG ) {
                error_log( 'Webshoptiger Catalog Sync: Blocked an attempt to delete non-synced product #' . $post->ID . '.' ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
            }
        }
    }

    /**
     * Has this product ever been created by Webshoptiger Catalog Sync (regardless of which
     * source site)? Any value in the 'supplier' meta field counts — the
     * specific source site ID doesn't matter here, only that it came in
     * via this plugin.
     */
    public static function is_synced_product( int $product_id ): bool {
        $supplier = get_post_meta( $product_id, self::META_KEY, true );
        return ! empty( $supplier );
    }

    // -------------------------------------------------------------------------
    // Check from the SOURCE SITE before an update (works without the plugin
    // on the destination site)
    // -------------------------------------------------------------------------

    /**
     * Check on the destination site whether the remote product belongs to
     * THIS source site. Called from Sync::push_single_product before a PUT.
     *
     * Returns true if:
     *  - the product no longer exists on the destination site (404) → safe to recreate
     *  - the product exists AND has supplier = our own supplier ID
     *  - the product exists but has NO supplier meta (not synced before,
     *    covers the very first sync before the meta is set)
     *
     * Returns false if the product has supplier meta that is NOT from this
     * source site (i.e. it's an own product on the destination site, or
     * from another source site that also syncs to this destination site).
     */
    public static function remote_product_is_ours( int $remote_id, array $site ): bool {
        $url   = trailingslashit( $site['site_url'] ) . 'wp-json/wc/v3/products/' . $remote_id;
        $creds = base64_encode( $site['api_key'] . ':' . $site['api_secret'] );

        $response = wp_remote_get( $url, [
            'timeout' => 10,
            'headers' => [ 'Authorization' => 'Basic ' . $creds ],
        ] );

        if ( is_wp_error( $response ) ) {
            // On a network error: be cautious and don't overwrite
            return false;
        }

        $code = wp_remote_retrieve_response_code( $response );

        // Product no longer exists on destination site — safe to recreate
        if ( $code === 404 ) {
            return true;
        }

        if ( $code !== 200 ) {
            return false;
        }

        $body        = json_decode( wp_remote_retrieve_body( $response ), true );
        $our_supplier = Settings::supplier_id();

        $found_supplier = null;
        foreach ( (array) ( $body['meta_data'] ?? [] ) as $meta ) {
            if ( $meta['key'] === self::META_KEY ) {
                $found_supplier = $meta['value'];
                break;
            }
        }

        // No supplier meta present = not synced before, safe to update
        if ( $found_supplier === null ) {
            return true;
        }

        // Supplier meta must match our own source site ID exactly
        return $found_supplier === $our_supplier;
    }
}
