<?php

namespace App\Services;

use Illuminate\Support\Facades\Crypt;

class SignatureService
{
    /**
     * Генерирует пару ключей для ЭЦП (приватный и публичный).
     * Приватный ключ сразу шифруется перед возвратом.
     *
     * @return array Массив с ключами: ['privateKey' => зашифрованный приватный ключ, 'publicKey' => публичный ключ]
     */
    public static function generateUserKeys(): array
    {
        // Конфигурация для генерации RSA ключа
        $config = [
            "private_key_bits" => 2048,
            "private_key_type" => OPENSSL_KEYTYPE_RSA,
        ];

        // Генерация новой пары ключей
        $res = openssl_pkey_new($config);

        // Извлекаем приватный ключ
        openssl_pkey_export($res, $privateKey);

        // Извлекаем публичный ключ
        $publicKeyDetails = openssl_pkey_get_details($res);
        $publicKey = $publicKeyDetails["key"];

        // Шифруем приватный ключ перед возвратом
        $encryptedPrivateKey = Crypt::encryptString($privateKey);

        return [
            'privateKey' => $encryptedPrivateKey,
            'publicKey'  => $publicKey,
        ];
    }

    /**
     * Подписывает данные с помощью приватного ключа.
     * Приватный ключ передается в зашифрованном виде и автоматически расшифровывается.
     *
     * @param string $data Данные для подписи (например, JSON)
     * @param string $encryptedPrivateKey Зашифрованный приватный ключ
     * @return string Base64-кодированная подпись
     */
    public static function signData(string $data, string $encryptedPrivateKey): string
    {
        // Расшифровываем приватный ключ
        $privateKey = Crypt::decryptString($encryptedPrivateKey);
        $signature = '';
        // Подписываем данные алгоритмом SHA256
        openssl_sign($data, $signature, $privateKey, OPENSSL_ALGO_SHA256);
        return base64_encode($signature);
    }

    /**
     * Проверяет подпись данных с помощью публичного ключа.
     *
     * @param string $data Исходные данные
     * @param string $signatureBase64 Base64-кодированная подпись
     * @param string $publicKey Публичный ключ
     * @return bool Результат проверки (true, если подпись верна)
     */
    public static function verifyData(string $data, string $signatureBase64, string $publicKey): bool
    {
        $signature = base64_decode($signatureBase64);
        $result = openssl_verify($data, $signature, $publicKey, OPENSSL_ALGO_SHA256);
        return $result === 1;
    }
}
