<?php

namespace Openguru\OpenCartFramework\TeleCartPulse;

class StartParamSerializer
{
    /**
     * Сериализовать массив параметров в строку для передачи в startapp
     *
     * Используется base64 кодирование JSON для безопасной передачи данных в URL
     *
     * @param array<string, mixed> $parameters Массив параметров для передачи
     * @return string Сериализованная строка параметров
     * @throws \InvalidArgumentException Если не удалось закодировать параметры
     */
    public static function serialize(array $parameters): string
    {
        if (empty($parameters)) {
            return '';
        }

        $json = json_encode($parameters, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);

        if ($json === false) {
            throw new \InvalidArgumentException('Failed to encode parameters to JSON: ' . json_last_error_msg());
        }

        // Используем base64 для безопасной передачи в URL
        $encoded = base64_encode($json);

        // Заменяем символы, которые могут вызвать проблемы в URL
        // + на -, / на _, убираем = в конце (padding)
        return rtrim(strtr($encoded, '+/', '-_'), '=');
    }

    /**
     * Десериализовать строку параметров обратно в массив
     *
     * @param string $serialized Сериализованная строка параметров
     * @return array<string, mixed> Массив параметров
     * @throws \InvalidArgumentException Если строка не может быть десериализована
     */
    public static function deserialize(string $serialized): array
    {
        if (empty($serialized)) {
            return [];
        }

        // Восстанавливаем base64 символы
        $encoded = strtr($serialized, '-_', '+/');

        // Добавляем padding если нужно
        $padding = strlen($encoded) % 4;
        if ($padding !== 0) {
            $encoded .= str_repeat('=', 4 - $padding);
        }

        $json = base64_decode($encoded, true);

        if ($json === false) {
            throw new \InvalidArgumentException('Failed to decode base64 string');
        }

        $parameters = json_decode($json, true);

        if (json_last_error() !== JSON_ERROR_NONE) {
            throw new \InvalidArgumentException('Failed to decode JSON: ' . json_last_error_msg());
        }

        if (! is_array($parameters)) {
            throw new \InvalidArgumentException('Decoded value is not an array');
        }

        return $parameters;
    }
}
