<?php

declare(strict_types=1);

namespace App\Service;

use App\Exception\MissingClientKeyException;
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpFoundation\Request;

final readonly class ClientKeyProvider
{
    public function __construct(
        private LoggerInterface $logger,
    ) {
    }

    public function fromRequest(Request $request): string
    {
        $ip = $this->extractClientIp($request);

        $clientKey = $this->hashIp($ip);
        $this->logger->debug('Generated client key for request.', [
            'client_key' => $clientKey,
        ]);

        return $clientKey;
    }

    private function extractClientIp(Request $request): string
    {
        $forwarded = $request->headers->get('X-Forwarded-For');
        if ($forwarded !== null && $forwarded !== '') {
            $parts = array_filter(array_map('trim', explode(',', $forwarded)));
            if ($parts !== []) {
                $this->logger->info('Resolved client address from forwarded header.', [
                    'resolution' => 'forwarded',
                ]);
                return $parts[0];
            }
        }

        $ip = $request->getClientIp();
        if (is_string($ip) && $ip !== '') {
            $this->logger->info('Resolved client address from remote address.', [
                'resolution' => 'remote',
            ]);
            return $ip;
        }

        $this->logger->critical('Failed to resolve client address for key generation.');
        throw new MissingClientKeyException();
    }

    private function hashIp(string $ip): string
    {
        return substr(hash('sha256', $ip), 0, 12);
    }
}
