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

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

const { Platform, NativeModules } = require('react-native');
const { WEB_DEVICE_ID_KEY } = require('../config/storageKeys'); //Ключи хранилища

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

//Генерация хэша из строки
const hashString = str => {
    let hash = 0;

    for (let i = 0; i < str.length; i++) {
        const char = str.charCodeAt(i);
        hash = (hash * 31 + char) % 2147483647;
    }

    return Math.abs(hash).toString(36);
};

//Генерация случайной части идентификатора
const generateRandomPart = () => {
    const timestamp = Date.now().toString(36);
    const random = Math.random().toString(36).substring(2, 10);
    return `${timestamp}${random}`;
};

//Получение fingerprint для Web
const getWebFingerprint = () => {
    if (typeof navigator === 'undefined' || typeof window === 'undefined') {
        return null;
    }

    const components = [
        navigator.userAgent || '',
        navigator.language || '',
        navigator.platform || '',
        new Date().getTimezoneOffset().toString(),
        window.screen?.width?.toString() || '',
        window.screen?.height?.toString() || '',
        window.screen?.colorDepth?.toString() || '',
        navigator.hardwareConcurrency?.toString() || '',
        navigator.maxTouchPoints?.toString() || ''
    ];

    return hashString(components.join('|'));
};

//Получение идентификатора для Web с сохранением в localStorage
const getWebDeviceId = () => {
    //Проверяем доступность localStorage через window
    const storage = typeof window !== 'undefined' ? window.localStorage : null;

    if (!storage) {
        //localStorage недоступен - генерируем на основе fingerprint
        const fingerprint = getWebFingerprint();
        return `WEB-${fingerprint || generateRandomPart()}`;
    }

    //Пробуем получить сохранённый идентификатор
    let deviceId = storage.getItem(WEB_DEVICE_ID_KEY);

    if (!deviceId) {
        //Генерируем новый идентификатор
        const fingerprint = getWebFingerprint();
        deviceId = `WEB-${fingerprint}-${generateRandomPart()}`;
        storage.setItem(WEB_DEVICE_ID_KEY, deviceId);
    }

    return deviceId;
};

//Получение ANDROID_ID через нативный модуль
const getAndroidId = async () => {
    try {
        //Пробуем получить через PlatformConstants
        if (NativeModules.PlatformConstants?.getAndroidID) {
            const androidId = await NativeModules.PlatformConstants.getAndroidID();

            if (androidId) {
                return androidId;
            }
        }

        //Пробуем получить через другие доступные модули
        if (NativeModules.RNDeviceInfo?.getAndroidId) {
            const androidId = await NativeModules.RNDeviceInfo.getAndroidId();

            if (androidId) {
                return androidId;
            }
        }

        //Пробуем получить из констант платформы
        const constants = Platform.constants || {};

        if (constants.Fingerprint) {
            return hashString(constants.Fingerprint);
        }

        return null;
    } catch (error) {
        console.warn('Не удалось получить Android ID:', error);
        return null;
    }
};

//Получение identifierForVendor для iOS
const getIosId = async () => {
    try {
        //Пробуем получить через доступные нативные модули
        if (NativeModules.RNDeviceInfo?.getUniqueId) {
            const uniqueId = await NativeModules.RNDeviceInfo.getUniqueId();

            if (uniqueId) {
                return uniqueId;
            }
        }

        if (NativeModules.SettingsManager?.settings?.AppleLocale) {
            //Используем комбинацию доступных данных для fingerprint
            const settings = NativeModules.SettingsManager.settings;
            const components = [settings.AppleLocale || '', settings.AppleLanguages?.join(',') || '', Platform.constants?.osVersion || ''];

            return hashString(components.join('|'));
        }

        return null;
    } catch (error) {
        console.warn('Не удалось получить iOS ID:', error);
        return null;
    }
};

//Генерация fingerprint для мобильных платформ
const getMobileFingerprint = () => {
    const constants = Platform.constants || {};

    const components = [
        Platform.OS,
        Platform.Version?.toString() || '',
        constants.Brand || '',
        constants.Model || '',
        constants.Manufacturer || '',
        constants.osVersion || '',
        constants.systemName || ''
    ];

    return hashString(components.filter(Boolean).join('|'));
};

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

//Получение постоянного идентификатора устройства
const getPersistentDeviceId = async () => {
    //Web платформа
    if (Platform.OS === 'web') {
        return getWebDeviceId();
    }

    //Android платформа
    if (Platform.OS === 'android') {
        const androidId = await getAndroidId();

        if (androidId) {
            return `AND-${androidId}`.toUpperCase();
        }

        //Fallback на fingerprint
        const fingerprint = getMobileFingerprint();
        return `AND-${fingerprint}-${generateRandomPart()}`.toUpperCase();
    }

    //iOS платформа
    if (Platform.OS === 'ios') {
        const iosId = await getIosId();

        if (iosId) {
            return `IOS-${iosId}`.toUpperCase();
        }

        //Fallback на fingerprint
        const fingerprint = getMobileFingerprint();
        return `IOS-${fingerprint}-${generateRandomPart()}`.toUpperCase();
    }

    //Неизвестная платформа
    return `UNK-${generateRandomPart()}`.toUpperCase();
};

//Проверка доступности постоянного идентификатора
const isPersistentIdAvailable = async () => {
    if (Platform.OS === 'web') {
        return typeof window !== 'undefined' && !!window.localStorage;
    }

    if (Platform.OS === 'android') {
        const androidId = await getAndroidId();
        return !!androidId;
    }

    if (Platform.OS === 'ios') {
        const iosId = await getIosId();
        return !!iosId;
    }

    return false;
};

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

module.exports = {
    getPersistentDeviceId,
    isPersistentIdAvailable
};
