<?php

declare(strict_types=1);

namespace CloudXM\NFe\Http\Controllers;

use CloudXM\NFe\Config\Configuration;
use CloudXM\NFe\Services\NFeWebhookProcessorService;
use CloudXM\SDK\Support\HasLogger;

/**
 * Receives webhook callbacks from the NFe server and delegates processing.
 *
 * Security:
 *  - HMAC-SHA256 signature verified via X-CloudXM-Signature header
 *  - Timestamp freshness enforced (±5 minutes) via X-CloudXM-Timestamp header
 *  - When no secret is configured, signature check is skipped (dev/test mode)
 */
class NFeWebhookController
{
    use HasLogger;

    public function __construct(
        private NFeWebhookProcessorService $processor,
        private Configuration $config
    ) {}

    // -------------------------------------------------------------------------
    // Task 11.2 — main handler
    // -------------------------------------------------------------------------

    public function handle(\WP_REST_Request $request): \WP_REST_Response
    {
        if (! $this->verifyTimestamp($request)) {
            $this->log()->warning('nfe.webhook_timestamp_expired', [
                'ts' => $request->get_header('X-CloudXM-Timestamp'),
            ]);
            return new \WP_REST_Response(['error' => 'Timestamp expired'], 401);
        }

        if (! $this->verifySignature($request)) {
            $this->log()->warning('nfe.webhook_invalid_signature');
            return new \WP_REST_Response(['error' => 'Invalid signature'], 401);
        }

        $payload = $request->get_json_params();

        $this->log()->info('nfe.webhook_received', [
            'event_type' => $payload['event_type'] ?? 'unknown',
        ]);

        $this->processor->process($payload ?? []);

        return new \WP_REST_Response(['ok' => true], 200);
    }

    // -------------------------------------------------------------------------
    // Task 11.3 — HMAC-SHA256 signature verification
    // -------------------------------------------------------------------------

    private function verifySignature(\WP_REST_Request $request): bool
    {
        $secret = $this->config->getWebhookSecret();

        // No secret configured → skip verification (dev/test mode)
        if ($secret === null) {
            return true;
        }

        $header = $request->get_header('X-CloudXM-Signature') ?? '';
        $body   = $request->get_body();

        $expected = 'sha256=' . hash_hmac('sha256', $body, $secret);

        return hash_equals($expected, $header);
    }

    // -------------------------------------------------------------------------
    // Task 11.4 — timestamp freshness check (±5 minutes)
    // -------------------------------------------------------------------------

    private function verifyTimestamp(\WP_REST_Request $request): bool
    {
        $ts = $request->get_header('X-CloudXM-Timestamp');

        if ($ts === null || ! ctype_digit((string) $ts)) {
            return false;
        }

        return abs(time() - (int) $ts) <= 300;
    }
}
