<?php

namespace App\Http\Middleware;

use App\Models\Carrier;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;

class VerifyEkartSignature
{
    public function handle(Request $request, Closure $next)
    {
        $carrier = Carrier::query()->where('slug', 'ekart')->first();
        $keys = $carrier?->getDecryptedApiKeys() ?? [];

        // Signature verification stays optional until Ekart confirms exact signature schema.
        $enforceSignature = filter_var($keys['webhook_enforce_signature'] ?? false, FILTER_VALIDATE_BOOL);
        if (!$enforceSignature) {
            return $next($request);
        }

        $secret = (string) ($keys['webhook_secret'] ?? '');
        if ($secret === '') {
            Log::warning('Ekart webhook signature enforcement enabled but secret missing');
            return response()->json(['error' => 'Webhook secret not configured'], 401);
        }

        $headerName = (string) ($keys['webhook_signature_header'] ?? 'X-Ekart-Signature');
        $headerValue = (string) $request->header($headerName, '');
        if ($headerValue === '') {
            Log::warning('Ekart webhook missing signature header', [
                'header' => $headerName,
            ]);
            return response()->json(['error' => 'Missing signature'], 401);
        }

        $prefix = (string) ($keys['webhook_signature_prefix'] ?? '');
        $receivedSignature = $this->stripPrefix($headerValue, $prefix);
        $expectedSignature = hash_hmac('sha256', $request->getContent(), $secret);

        if (!hash_equals($expectedSignature, $receivedSignature)) {
            Log::warning('Ekart webhook signature mismatch', [
                'header' => $headerName,
            ]);
            return response()->json(['error' => 'Invalid signature'], 401);
        }

        return $next($request);
    }

    protected function stripPrefix(string $signature, string $prefix): string
    {
        if ($prefix === '') {
            return trim($signature);
        }

        $trimmed = trim($signature);
        $prefixLength = strlen($prefix);

        if (strncasecmp($trimmed, $prefix, $prefixLength) === 0) {
            return trim(substr($trimmed, $prefixLength));
        }

        return $trimmed;
    }
}
