<?php

namespace App\Tests\Service;

use App\Service\AnalyticsCryptoService;
use PHPUnit\Framework\TestCase;

class AnalyticsCryptoServiceTest extends TestCase
{
    private AnalyticsCryptoService $service;

    protected function setUp(): void
    {
        $this->service = new AnalyticsCryptoService('test_secret_key_for_analytics');
    }

    public function testEncryptDecryptRoundTrip(): void
    {
        $data = ['uid' => 'abc-123', 'url' => '/test', 'title' => 'Test Page'];

        $encrypted = $this->service->encrypt($data);
        self::assertNotEmpty($encrypted);

        $decrypted = $this->service->decrypt($encrypted);
        self::assertSame($data, $decrypted);
    }

    public function testDecryptInvalidPayloadReturnsNull(): void
    {
        self::assertNull($this->service->decrypt('invalid_base64'));
        self::assertNull($this->service->decrypt(base64_encode('short')));
    }

    public function testDecryptTamperedPayloadReturnsNull(): void
    {
        $encrypted = $this->service->encrypt(['test' => true]);
        $tampered = substr($encrypted, 0, -2).'AA';

        self::assertNull($this->service->decrypt($tampered));
    }

    public function testGenerateAndVerifyVisitorHash(): void
    {
        $uid = 'test-uid-123';
        $hash = $this->service->generateVisitorHash($uid);

        self::assertNotEmpty($hash);
        self::assertTrue($this->service->verifyVisitorHash($uid, $hash));
    }

    public function testVerifyVisitorHashRejectsTampered(): void
    {
        $uid = 'test-uid-123';
        $hash = $this->service->generateVisitorHash($uid);

        self::assertFalse($this->service->verifyVisitorHash('different-uid', $hash));
        self::assertFalse($this->service->verifyVisitorHash($uid, 'wrong_hash'));
    }

    public function testGetKeyForJsReturnsBase64(): void
    {
        $key = $this->service->getKeyForJs();
        self::assertNotEmpty($key);
        self::assertNotFalse(base64_decode($key, true));
    }

    public function testDifferentSecretsProduceDifferentKeys(): void
    {
        $service2 = new AnalyticsCryptoService('different_secret');

        $uid = 'test-uid';
        $hash1 = $this->service->generateVisitorHash($uid);
        $hash2 = $service2->generateVisitorHash($uid);

        self::assertNotSame($hash1, $hash2);
    }

    public function testEncryptedDataCannotBeDecryptedByDifferentKey(): void
    {
        $service2 = new AnalyticsCryptoService('different_secret');

        $encrypted = $this->service->encrypt(['test' => true]);
        self::assertNull($service2->decrypt($encrypted));
    }
}
