/**
 * @file ConfigManager.cpp
 * @brief 配置管理器实现
 * @author BattlefieldExplorationSystem Team
 * @date 2024-01-01
 * @version 2.0
 */

#include "utils/ConfigManager.h"

// C++标准库头文件
#include <iostream>

// Qt头文件
#include <QCoreApplication>
#include <QCryptographicHash>
#include <QDebug>
#include <QDir>
#include <QStandardPaths>

// 静态成员初始化
std::unique_ptr<ConfigManager> ConfigManager::m_instance = nullptr;
std::mutex ConfigManager::m_instanceMutex;

ConfigManager& ConfigManager::getInstance()
{
    std::lock_guard<std::mutex> lock(m_instanceMutex);
    if (!m_instance) {
        // 使用make_unique需要public构造函数，这里使用reset
        m_instance.reset(new ConfigManager());
    }
    return *m_instance;
}

ConfigManager::ConfigManager(QObject* parent)
    : QObject(parent)
    , m_initialized(false)
{
    // 私有构造函数，仅供getInstance调用
}

ConfigManager::~ConfigManager()
{
    if (m_settings && m_initialized) {
        save();
    }
}

bool ConfigManager::initialize(const QString& configFilePath)
{
    std::lock_guard<std::mutex> lock(m_mutex);
    
    if (m_initialized) {
        qWarning() << "ConfigManager already initialized";
        return true;
    }

    // 确定配置文件路径
    if (configFilePath.isEmpty()) {
        // 使用默认路径
        QString configDir = QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation);
        QDir().mkpath(configDir);
        m_configFilePath = configDir + "/config.ini";
    } else {
        m_configFilePath = configFilePath;
    }

    // 创建QSettings对象
    m_settings = std::make_unique<QSettings>(m_configFilePath, QSettings::IniFormat);
    m_settings->setIniCodec("UTF-8");

    // 加载默认配置
    loadDefaultConfig();
    
    // 从环境变量加载敏感配置
    loadFromEnvironment();

    m_initialized = true;
    qDebug() << "ConfigManager initialized with config file:" << m_configFilePath;
    
    return true;
}

void ConfigManager::loadDefaultConfig()
{
    // 数据库默认配置
    if (!m_settings->contains(KEY_DB_HOST)) {
        m_settings->setValue(KEY_DB_HOST, "localhost");
    }
    if (!m_settings->contains(KEY_DB_PORT)) {
        m_settings->setValue(KEY_DB_PORT, 3306);
    }
    if (!m_settings->contains(KEY_DB_NAME)) {
        m_settings->setValue(KEY_DB_NAME, "Client");
    }
    if (!m_settings->contains(KEY_DB_USER)) {
        m_settings->setValue(KEY_DB_USER, "root");
    }

    // UI默认配置
    if (!m_settings->contains("ui/window_width")) {
        m_settings->setValue("ui/window_width", 1400);
    }
    if (!m_settings->contains("ui/window_height")) {
        m_settings->setValue("ui/window_height", 1000);
    }
    if (!m_settings->contains("ui/window_margin")) {
        m_settings->setValue("ui/window_margin", 100);
    }

    // 系统默认配置
    if (!m_settings->contains("system/log_level")) {
        m_settings->setValue("system/log_level", "INFO");
    }
    if (!m_settings->contains("system/auto_save_interval")) {
        m_settings->setValue("system/auto_save_interval", 300); // 5分钟
    }
}

void ConfigManager::loadFromEnvironment()
{
    // 简化配置加载，使用固定的数据库配置便于项目交接
    qDebug() << "Loading default database configuration for project handover";
    
    // 可选：仍然支持从环境变量加载数据库主机（如果需要）
    const char* dbHost = std::getenv("BES_DB_HOST");
    if (dbHost && strlen(dbHost) > 0) {
        m_settings->setValue(KEY_DB_HOST, QString::fromUtf8(dbHost));
        qDebug() << "Using database host from environment:" << dbHost;
    }

    // 可选：仍然支持从环境变量加载数据库用户名（如果需要）
    const char* dbUser = std::getenv("BES_DB_USER");
    if (dbUser && strlen(dbUser) > 0) {
        m_settings->setValue(KEY_DB_USER, QString::fromUtf8(dbUser));
        qDebug() << "Using database user from environment:" << dbUser;
    }
}

QString ConfigManager::getDatabaseHost() const
{
    return getValue<QString>(KEY_DB_HOST, "localhost");
}

int ConfigManager::getDatabasePort() const
{
    return getValue<int>(KEY_DB_PORT, 3306);
}

QString ConfigManager::getDatabaseName() const
{
    return getValue<QString>(KEY_DB_NAME, "Client");
}

QString ConfigManager::getDatabaseUser() const
{
    return getValue<QString>(KEY_DB_USER, "root");
}

QString ConfigManager::getDatabasePassword() const
{
    // 直接返回项目固定密码，便于团队协作和项目交接
    qDebug() << "Using hardcoded database password for project handover";
    return QString("hzk200407140238");
}

void ConfigManager::setDatabaseConfig(const QString& host, int port, const QString& database,
                                     const QString& user, const QString& password)
{
    {
        std::lock_guard<std::mutex> lock(m_mutex);
        m_settings->setValue(KEY_DB_HOST, host);
        m_settings->setValue(KEY_DB_PORT, port);
        m_settings->setValue(KEY_DB_NAME, database);
        m_settings->setValue(KEY_DB_USER, user);
        
        if (!password.isEmpty()) {
            QString encryptedPassword = encryptString(password);
            m_settings->setValue(KEY_DB_PASSWORD, encryptedPassword);
        }
        
        m_settings->sync();
    }
    
    // 发送配置变更信号
    emit configurationChanged("database");
}

bool ConfigManager::contains(const QString& key) const
{
    std::lock_guard<std::mutex> lock(m_mutex);
    return m_settings->contains(key);
}

void ConfigManager::remove(const QString& key)
{
    {
        std::lock_guard<std::mutex> lock(m_mutex);
        m_settings->remove(key);
        m_settings->sync();
    }
    emit configurationChanged(key);
}

void ConfigManager::save()
{
    std::lock_guard<std::mutex> lock(m_mutex);
    if (m_settings) {
        m_settings->sync();
        qDebug() << "Configuration saved to:" << m_configFilePath;
    }
}

void ConfigManager::reload()
{
    std::lock_guard<std::mutex> lock(m_mutex);
    if (m_settings) {
        m_settings->sync();
        loadFromEnvironment(); // 重新加载环境变量
        qDebug() << "Configuration reloaded from:" << m_configFilePath;
    }
}

QString ConfigManager::encryptString(const QString& plainText) const
{
    if (plainText.isEmpty()) {
        return QString();
    }

    // 简单的加密实现（实际项目中应使用更强的加密算法）
    QByteArray key = generateKey();
    QByteArray data = plainText.toUtf8();
    
    // 异或加密
    for (int i = 0; i < data.size(); ++i) {
        data[i] = data[i] ^ key[i % key.size()];
    }
    
    return QString::fromLatin1(data.toBase64());
}

QString ConfigManager::decryptString(const QString& encryptedText) const
{
    if (encryptedText.isEmpty()) {
        return QString();
    }

    QByteArray key = generateKey();
    QByteArray data = QByteArray::fromBase64(encryptedText.toLatin1());
    
    // 异或解密
    for (int i = 0; i < data.size(); ++i) {
        data[i] = data[i] ^ key[i % key.size()];
    }
    
    return QString::fromUtf8(data);
}

QByteArray ConfigManager::generateKey() const
{
    // 基于应用程序信息生成密钥
    QString keySource = QCoreApplication::applicationName() + 
                       QCoreApplication::organizationName() + 
                       "BattlefieldExplorationSystem";
    
    return QCryptographicHash::hash(keySource.toUtf8(), QCryptographicHash::Sha256);
}