<?php

declare(strict_types=1);

namespace App\Framework\Http\Session;

use App\Framework\Redis\RedisConnectionInterface;
use Redis;

/**
 * Implementation of the SessionStorage interface using Redis as the storage backend.
 * This class provides methods to read, write, remove, and migrate session data stored in Redis.
 */
final class RedisSessionStorage implements SessionStorage
{
    private const string PREFIX = 'session:';

    private Redis $redis;

    public function __construct(
        private readonly RedisConnectionInterface $connection,
        private readonly int $ttl = 3600 // 1 Stunde standardmäßig
    ) {
        $this->redis = $this->connection->getClient();
    }

    public function read(SessionId $id): array
    {
        $data = $this->redis->get($this->getKey($id));

        // Redis kann false oder null zurückgeben wenn der Key nicht existiert
        if ($data === false || $data === null || ! is_string($data)) {
            return [];
        }

        // Validiere JSON bevor Dekodierung
        if (! json_validate($data)) {
            error_log("RedisSessionStorage: Invalid JSON data for session " . $id->toString());

            return [];
        }

        return json_decode($data, true) ?? [];
    }

    public function write(SessionId $id, array $data): void
    {
        $this->redis->setex(
            $this->getKey($id),
            $this->ttl,
            json_encode($data)
        );
    }

    public function remove(SessionId $id): void
    {
        $this->redis->del($this->getKey($id));
    }

    public function migrate(SessionId $fromId, SessionId $toId): void
    {
        $data = $this->read($fromId);
        $this->write($toId, $data);
        $this->remove($fromId);
    }

    private function getKey(SessionId $id): string
    {
        return self::PREFIX . $id->toString();
    }
}
