<?php
/**
 * Generic Webhook CDN Adapter
 *
 * Implements CDN provider interface for custom webhook integrations,
 * allowing purge notifications to be sent to any HTTP endpoint.
 *
 * @package Mamba\Modules\CDN\Services
 * @since   1.0.0
 */

namespace Mamba\Modules\CDN\Services;

/**
 * Class GenericWebhookAdapter
 *
 * Generic webhook adapter that sends cache purge notifications to a
 * configurable HTTP endpoint with optional HMAC signature verification.
 *
 * @since 1.0.0
 */
final class GenericWebhookAdapter implements Provider {
    private string $webhookUrl;
    private string $webhookSecret;
    
    public function __construct(string $webhookUrl, string $webhookSecret = '') {
        $this->webhookUrl = $webhookUrl;
        $this->webhookSecret = $webhookSecret;
    }
    
    public function isConnected(): bool {
        return !empty($this->webhookUrl);
    }
    
    public function getName(): string {
        return 'generic';
    }
    
    public function purgeUrls(array $urls, array $headerCombos = []): Result {
        if (empty($urls)) {
            return Result::success('No URLs to purge');
        }
        
        $payload = [
            'action' => 'purge_urls',
            'urls' => array_values(array_unique($urls)),
            'timestamp' => time(),
            'site_url' => get_site_url()
        ];
        
        if (!empty($headerCombos)) {
            $payload['header_combos'] = $headerCombos;
        }
        
        return $this->sendWebhook($payload);
    }
    
    public function purgeTags(array $tags): Result {
        if (empty($tags)) {
            return Result::success('No tags to purge');
        }
        
        $payload = [
            'action' => 'purge_tags',
            'tags' => array_values(array_unique($tags)),
            'timestamp' => time(),
            'site_url' => get_site_url()
        ];
        
        return $this->sendWebhook($payload);
    }
    
    public function purgeAll(): Result {
        $payload = [
            'action' => 'purge_all',
            'timestamp' => time(),
            'site_url' => get_site_url()
        ];
        
        return $this->sendWebhook($payload);
    }
    
    public function applyRecommendedSettings(): Result {
        // Generic webhook doesn't have settings to apply
        return Result::success('No recommended settings to apply for generic webhook');
    }
    
    public function testConnection(): Result {
        $payload = [
            'action' => 'test_connection',
            'timestamp' => time(),
            'site_url' => get_site_url()
        ];
        
        return $this->sendWebhook($payload);
    }
    
    /**
     * Send webhook payload to the configured endpoint
     */
    private function sendWebhook(array $payload): Result {
        $args = [
            'method' => 'POST',
            'headers' => [
                'Content-Type' => 'application/json',
                'User-Agent' => 'Mamba-WooCommerce-CDN/1.0',
                'X-Mamba-Signature' => $this->generateSignature($payload)
            ],
            'body' => wp_json_encode($payload),
            'timeout' => 30,
            'sslverify' => true
        ];
        
        $response = wp_remote_post($this->webhookUrl, $args);
        
        if (is_wp_error($response)) {
            return Result::error('Webhook request failed: ' . $response->get_error_message());
        }
        
        $statusCode = wp_remote_retrieve_response_code($response);
        $body = wp_remote_retrieve_body($response);
        
        if ($statusCode >= 200 && $statusCode < 300) {
            return Result::success('Webhook sent successfully', ['response' => $body]);
        }
        
        return Result::error("Webhook failed with status {$statusCode}: {$body}", $statusCode);
    }
    
    /**
     * Generate signature for webhook security
     */
    private function generateSignature(array $payload): string {
        if (empty($this->webhookSecret)) {
            return '';
        }
        
        $data = wp_json_encode($payload);
        return hash_hmac('sha256', $data, $this->webhookSecret);
    }
}
