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

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

const { open } = require('react-native-quick-sqlite'); //Открытие БД SQLite
const SQLFileLoader = require('./sql/SQLFileLoader'); //Загрузчик SQL-файлов
const { DB_NAME } = require('../config/database'); //Имя базы данных

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

class SQLiteDatabase {
    constructor() {
        this.db = null;
        this.isInitialized = false;
        this.sqlQueries = null;
    }

    //Инициализация базы данных
    async initialize() {
        if (this.isInitialized) {
            return this.db;
        }

        try {
            //Загружаем SQL файлы (синхронно)
            this.sqlQueries = SQLFileLoader.loadAllSQLFiles();

            //Открываем базу данных
            this.db = open({
                name: DB_NAME,
                location: 'default'
            });

            //Настраиваем базу данных
            await this.setupDatabase();

            this.isInitialized = true;
            return this.db;
        } catch (error) {
            throw error;
        }
    }

    //Настройка базы данных (создание таблиц и индексов)
    async setupDatabase() {
        if (!this.db || !this.sqlQueries) {
            throw new Error('База данных или SQL запросы не инициализированы');
        }

        try {
            //Выполняем SQL запросы последовательно
            await this.executeQuery(this.sqlQueries.CREATE_TABLE_APP_SETTINGS);

            await this.executeQuery(this.sqlQueries.CREATE_TABLE_AUTH_SESSION);
        } catch (error) {
            throw error;
        }
    }

    //Выполнение SQL запроса
    async executeQuery(sql, params = []) {
        if (!this.db) {
            throw new Error('База данных не инициализирована');
        }

        try {
            const result = await this.db.executeAsync(sql, params);
            return result;
        } catch (error) {
            throw error;
        }
    }

    //Получение настройки
    async getSetting(key) {
        try {
            const result = await this.executeQuery(this.sqlQueries.SETTINGS_GET, [key]);

            if (result.rows && result.rows.length > 0) {
                return result.rows.item(0).value;
            }
            return null;
        } catch (error) {
            throw error;
        }
    }

    //Сохранение настройки
    async setSetting(key, value) {
        try {
            const stringValue = typeof value === 'object' ? JSON.stringify(value) : String(value);
            await this.executeQuery(this.sqlQueries.SETTINGS_SET, [key, stringValue]);
            return true;
        } catch (error) {
            throw error;
        }
    }

    //Удаление настройки
    async deleteSetting(key) {
        try {
            await this.executeQuery(this.sqlQueries.SETTINGS_DELETE, [key]);
            return true;
        } catch (error) {
            throw error;
        }
    }

    //Получение всех настроек
    async getAllSettings() {
        try {
            const result = await this.executeQuery(this.sqlQueries.SETTINGS_GET_ALL, []);
            const settings = {};

            if (result.rows && result.rows.length > 0) {
                for (let i = 0; i < result.rows.length; i++) {
                    const row = result.rows.item(i);
                    try {
                        settings[row.key] = JSON.parse(row.value);
                    } catch {
                        settings[row.key] = row.value;
                    }
                }
            }

            return settings;
        } catch (error) {
            throw error;
        }
    }

    //Очистка всех настроек
    async clearSettings() {
        try {
            await this.executeQuery(this.sqlQueries.SETTINGS_CLEAR_ALL, []);
            return true;
        } catch (error) {
            throw error;
        }
    }

    //Оптимизация базы данных
    async vacuum() {
        try {
            await this.executeQuery(this.sqlQueries.UTILITY_VACUUM, []);
            return true;
        } catch (error) {
            throw error;
        }
    }

    //Сохранение сессии авторизации
    async setAuthSession(session) {
        try {
            const {
                sessionId,
                serverUrl,
                userRn = null,
                userCode = null,
                userName = null,
                companyRn = null,
                companyName = null,
                savePassword = false
            } = session;

            await this.executeQuery(this.sqlQueries.AUTH_SESSION_SET, [
                sessionId,
                serverUrl,
                userRn,
                userCode,
                userName,
                companyRn,
                companyName,
                savePassword ? 1 : 0
            ]);
            return true;
        } catch (error) {
            throw error;
        }
    }

    //Получение сессии авторизации
    async getAuthSession() {
        try {
            const result = await this.executeQuery(this.sqlQueries.AUTH_SESSION_GET, []);

            if (result.rows && result.rows.length > 0) {
                const row = result.rows.item(0);
                return {
                    sessionId: row.session_id,
                    serverUrl: row.server_url,
                    userRn: row.user_rn,
                    userCode: row.user_code,
                    userName: row.user_name,
                    companyRn: row.company_rn,
                    companyName: row.company_name,
                    savePassword: row.save_password === 1,
                    createdAt: row.created_at,
                    updatedAt: row.updated_at
                };
            }
            return null;
        } catch (error) {
            throw error;
        }
    }

    //Очистка сессии авторизации
    async clearAuthSession() {
        try {
            await this.executeQuery(this.sqlQueries.AUTH_SESSION_CLEAR, []);
            return true;
        } catch (error) {
            throw error;
        }
    }

    //Проверка существования таблицы
    async checkTableExists(tableName) {
        try {
            const result = await this.executeQuery(this.sqlQueries.UTILITY_CHECK_TABLE, [tableName]);
            return result.rows && result.rows.length > 0 && result.rows.item(0).exists === 1;
        } catch (error) {
            throw error;
        }
    }

    //Удаление таблицы
    async dropTable(tableName) {
        try {
            await this.executeQuery(this.sqlQueries.UTILITY_DROP_TABLE, [tableName]);
            return true;
        } catch (error) {
            throw error;
        }
    }

    //Закрытие базы данных
    async close() {
        try {
            if (this.db) {
                //В react-native-quick-sqlite нет явного метода close
                //База данных закрывается автоматически при уничтожении объекта
                this.db = null;
                this.isInitialized = false;
            }
        } catch (error) {
            this.db = null;
            this.isInitialized = false;
            throw error;
        }
    }
}

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

module.exports = new SQLiteDatabase();
