<?php

namespace RecastPaywall\Services;

/**
 * Webhook handler for Recast events
 */
class WebhookHandler {
    /**
     * Entitlement service
     */
    private EntitlementService $entitlementService;

    /**
     * Constructor
     */
    public function __construct(EntitlementService $entitlementService) {
        $this->entitlementService = $entitlementService;
    }

    /**
     * Handle webhook request
     */
    public function handle(): void {
        // Verify webhook signature
        if (!$this->verifySignature()) {
            http_response_code(401);
            exit('Unauthorized');
        }

        // Get webhook payload
        $payload = $this->getPayload();
        
        if (!$payload) {
            http_response_code(400);
            exit('Invalid payload');
        }

        // Process webhook
        $this->processWebhook($payload);

        http_response_code(200);
        exit('OK');
    }

    /**
     * Verify webhook signature
     */
    private function verifySignature(): bool {
        $signature = isset($_SERVER['HTTP_X_RECAST_SIGNATURE']) ? sanitize_text_field(wp_unslash($_SERVER['HTTP_X_RECAST_SIGNATURE'])) : '';
        
        if (empty($signature)) {
            return false;
        }

        $settings = get_option('recast_paywall_settings', []);
        $secret = $settings['api_secret'] ?? '';
        
        if (empty($secret)) {
            return false;
        }

        $payload = file_get_contents('php://input');
        $expectedSignature = hash_hmac('sha256', $payload, $secret);
        
        return hash_equals($expectedSignature, $signature);
    }

    /**
     * Get webhook payload
     */
    private function getPayload(): ?array {
        $payload = file_get_contents('php://input');
        $data = json_decode($payload, true);
        
        return is_array($data) ? $data : null;
    }

    /**
     * Process webhook
     */
    private function processWebhook(array $payload): void {
        $event = $payload['event'] ?? '';
        
        switch ($event) {
            case 'entitlement.created':
            case 'entitlement.updated':
            case 'entitlement.deleted':
                $this->handleEntitlementEvent($payload);
                break;
                
            case 'product.created':
            case 'product.updated':
            case 'product.deleted':
                $this->handleInventoryEvent($payload);
                break;
                
            default:
                // Unknown event, log it
                $this->logWebhook('Unknown webhook event', $payload);
                break;
        }
    }

    /**
     * Handle entitlement events
     */
    private function handleEntitlementEvent(array $payload): void {
        $data = $payload['data'] ?? [];
        $externalUserId = $data['externalUserId'] ?? '';
        $externalProductId = $data['externalProductId'] ?? '';
        
        if (empty($externalUserId) || empty($externalProductId)) {
            $this->logWebhook('Invalid entitlement event data', $payload);
            return;
        }

        // Clear entitlement cache for this user/product combination
        $this->entitlementService->clearCache(
            intval($externalProductId),
            intval($externalUserId)
        );

        $this->logWebhook('Entitlement cache cleared', [
            'user_id' => $externalUserId,
            'product_id' => $externalProductId,
            'event' => $payload['event'],
        ]);
    }

    /**
     * Handle inventory events
     */
    private function handleInventoryEvent(array $payload): void {
        $data = $payload['data'] ?? [];
        $externalProductId = $data['externalProductId'] ?? '';
        
        if (empty($externalProductId)) {
            $this->logWebhook('Invalid inventory event data', $payload);
            return;
        }

        $postId = intval($externalProductId);
        
        // Update post meta if needed
        if (isset($data['id'])) {
            update_post_meta($postId, '_recast_inventory_item_id', $data['id']);
        }

        // Update sync timestamp
        update_post_meta($postId, '_recast_last_synced_at', current_time('mysql'));

        // Clear any retry count
        delete_post_meta($postId, '_recast_sync_retry_count');

        $this->logWebhook('Inventory updated', [
            'post_id' => $postId,
            'item_id' => $data['id'] ?? null,
            'event' => $payload['event'],
        ]);
    }

    /**
     * Log webhook
     */
    private function logWebhook(string $message, array $context = []): void {
        // Debug logging removed for production
    }
}
