/*
    Предрейсовые осмотры - мобильное приложение
    Утилиты безопасного хранения данных
*/

//---------------------
//Подключение библиотек
//---------------------

const { ENCRYPTED_PREFIX, SECRET_KEY_LENGTH } = require('../config/storageKeys'); //Ключи и константы хранилища

//-----------------------
//Вспомогательные функции
//-----------------------

//Вычисление XOR двух байтов через арифметические операции
const xorByte = (a, b) => {
    let result = 0;
    let bit = 1;

    //Обрабатываем каждый из 8 бит
    for (let i = 0; i < 8; i++) {
        const bitA = Math.floor(a / bit) % 2;
        const bitB = Math.floor(b / bit) % 2;

        //XOR: результат 1 только если биты разные
        if (bitA !== bitB) {
            result += bit;
        }

        bit *= 2;
    }

    return result;
};

//Генерация хэша ключа на основе секретного ключа и соли
const generateKeyHash = (secretKey, salt) => {
    const combined = secretKey + salt;
    const hash = [];

    for (let i = 0; i < combined.length; i++) {
        hash.push(combined.charCodeAt(i) % 256);
    }

    //Расширяем хэш до 256 байт для лучшего распределения
    while (hash.length < 256) {
        const newByte = (hash[hash.length - 1] + hash[hash.length - 2] + hash.length) % 256;
        hash.push(newByte);
    }

    return hash;
};

//XOR-шифрование строки с использованием ключа
const xorEncrypt = (text, keyHash) => {
    const result = [];

    for (let i = 0; i < text.length; i++) {
        const charCode = text.charCodeAt(i);
        const keyByte = keyHash[i % keyHash.length];
        result.push(xorByte(charCode, keyByte));
    }

    //Конвертируем в hex-строку
    return result.map(byte => byte.toString(16).padStart(2, '0')).join('');
};

//XOR-расшифрование строки
const xorDecrypt = (encryptedHex, keyHash) => {
    const bytes = [];

    //Разбираем hex-строку на байты
    for (let i = 0; i < encryptedHex.length; i += 2) {
        bytes.push(parseInt(encryptedHex.substr(i, 2), 16));
    }

    //Расшифровываем XOR
    const result = [];
    for (let i = 0; i < bytes.length; i++) {
        const keyByte = keyHash[i % keyHash.length];
        result.push(String.fromCharCode(xorByte(bytes[i], keyByte)));
    }

    return result.join('');
};

//-----------
//Тело модуля
//-----------

//Генерация уникального секретного ключа для устройства
const generateSecretKey = () => {
    const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%&*()-_=+[]{}|;:,.<>?';
    const timestamp = Date.now().toString(36);
    let key = '';

    //Генерируем случайную часть ключа
    for (let i = 0; i < SECRET_KEY_LENGTH; i++) {
        const randomIndex = Math.floor(Math.random() * characters.length);
        key += characters[randomIndex];
    }

    //Добавляем временную метку для уникальности
    return `${key}_${timestamp}`;
};

//Шифрование чувствительных данных
const encryptData = (data, secretKey, salt = '') => {
    if (!data) {
        return '';
    }

    if (!secretKey) {
        console.error('Ошибка шифрования: секретный ключ не предоставлен');
        return '';
    }

    try {
        const keyHash = generateKeyHash(secretKey, salt);
        const encrypted = xorEncrypt(data, keyHash);
        return ENCRYPTED_PREFIX + encrypted;
    } catch (error) {
        console.error('Ошибка шифрования:', error);
        return '';
    }
};

//Расшифрование данных
const decryptData = (encryptedData, secretKey, salt = '') => {
    if (!encryptedData) {
        return '';
    }

    if (!secretKey) {
        console.error('Ошибка расшифровки: секретный ключ не предоставлен');
        return '';
    }

    //Проверяем префикс
    if (!encryptedData.startsWith(ENCRYPTED_PREFIX)) {
        //Данные не зашифрованы - возвращаем как есть (для обратной совместимости)
        return encryptedData;
    }

    try {
        const encryptedHex = encryptedData.slice(ENCRYPTED_PREFIX.length);
        const keyHash = generateKeyHash(secretKey, salt);
        return xorDecrypt(encryptedHex, keyHash);
    } catch (error) {
        console.error('Ошибка расшифровки:', error);
        return '';
    }
};

//Проверка зашифрованы ли данные
const isEncrypted = data => {
    return data && data.startsWith(ENCRYPTED_PREFIX);
};

//----------------
//Интерфейс модуля
//----------------

module.exports = {
    generateSecretKey,
    encryptData,
    decryptData,
    isEncrypted
};
