<?php

declare(strict_types=1);

namespace App\Framework\Http\Session\Fingerprint;

use App\Framework\UserAgent\UserAgent;

final readonly class FingerprintData
{
    public function __construct(
        public ?UserAgent $userAgent = null,
        public ?string $acceptLanguage = null,
        public ?string $acceptEncoding = null,
        public ?string $ipPrefix = null,
        public ?string $secChUa = null,
        public ?string $dnt = null,
    ) {
    }

    /**
     * @return array<string, ?string>
     */
    public function toArray(): array
    {
        return [
            'user_agent' => $this->userAgent?->value,
            'accept_language' => $this->acceptLanguage,
            'accept_encoding' => $this->acceptEncoding,
            'ip_prefix' => $this->ipPrefix,
            'sec_ch_ua' => $this->secChUa,
            'dnt' => $this->dnt,
        ];
    }

    /**
     * @param array<string, ?string> $data
     * @return self
     */
    public static function fromArray(array $data): self
    {
        $userAgentString = $data['user_agent'] ?? null;
        $userAgent = $userAgentString ? UserAgent::fromString($userAgentString) : null;

        return new self(
            userAgent: $userAgent,
            acceptLanguage: $data['accept_language'] ?? null,
            acceptEncoding: $data['accept_encoding'] ?? null,
            ipPrefix: $data['ip_prefix'] ?? null,
            secChUa: $data['sec_ch_ua'] ?? null,
            dnt: $data['dnt'] ?? null,
        );
    }

    /**
     * @param FingerprintData $other
     * @return string[]
     */
    public function getMismatchingComponents(FingerprintData $other): array
    {
        $mismatches = [];
        $thisArray = $this->toArray();
        $otherArray = $other->toArray();

        foreach ($thisArray as $key => $value) {
            if ($value !== $otherArray[$key]) {
                $mismatches[] = $key;
            }
        }

        return $mismatches;
    }
}
