// DragonX Wallet - ImGui Edition
// Copyright 2024-2026 The Hush Developers
// Released under the GPLv3

#include "settings_window.h"
#include "../../app.h"
#include "../../config/version.h"
#include "../../config/settings.h"
#include "../../util/i18n.h"
#include "../../util/platform.h"
#include "../../rpc/rpc_client.h"
#include "../theme.h"
#include "../schema/ui_schema.h"
#include "../schema/skin_manager.h"
#include "../notifications.h"
#include "../effects/imgui_acrylic.h"
#include "../material/draw_helpers.h"
#include "../../embedded/IconsMaterialDesign.h"
#include "imgui.h"
#include <vector>
#include <filesystem>

// Icon text for settings UI
#define ICON_CUSTOM_THEME   ICON_MD_TUNE
#define ICON_REFRESH_THEMES ICON_MD_REFRESH

namespace dragonx {
namespace ui {

// Helper: build "TranslatedLabel##id" for ImGui widgets that use label as ID
static std::string TrId(const char* tr_key, const char* id) {
    std::string s = TR(tr_key);
    s += "##";
    s += id;
    return s;
}

// Settings state - these get loaded from Settings on window open
static bool s_initialized = false;
static int s_language_index = 0;
static bool s_save_ztxs = true;
static bool s_allow_custom_fees = false;
static bool s_auto_shield = false;
static bool s_fetch_prices = true;
static bool s_use_tor = false;
static char s_rpc_host[128] = DRAGONX_DEFAULT_RPC_HOST;
static char s_rpc_port[16] = DRAGONX_DEFAULT_RPC_PORT;
static char s_rpc_user[64] = "";
static char s_rpc_password[64] = "";
static char s_tx_explorer[256] = "https://explorer.dragonx.is/tx/";
static char s_addr_explorer[256] = "https://explorer.dragonx.is/address/";

// Acrylic settings
static bool s_acrylic_enabled = true;
static float s_blur_amount = 1.5f;  // 0.0=Off, continuous blur multiplier
static float s_noise_opacity = 0.5f;
static bool s_reduced_transparency = false;  // Accessibility option
static bool s_gradient_background = false;   // Gradient background mode

// Saved skin ID for cancel/revert
static std::string s_saved_skin_id;

// Load current settings into UI state
static void loadSettingsToUI(config::Settings* settings) {
    if (!settings) return;
    
    s_saved_skin_id = settings->getSkinId();
    s_save_ztxs = settings->getSaveZtxs();
    s_allow_custom_fees = settings->getAllowCustomFees();
    s_auto_shield = settings->getAutoShield();
    s_fetch_prices = settings->getFetchPrices();
    s_use_tor = settings->getUseTor();
    
    strncpy(s_tx_explorer, settings->getTxExplorerUrl().c_str(), sizeof(s_tx_explorer) - 1);
    strncpy(s_addr_explorer, settings->getAddressExplorerUrl().c_str(), sizeof(s_addr_explorer) - 1);
    
    // Set language index
    auto& i18n = util::I18n::instance();
    const auto& languages = i18n.getAvailableLanguages();
    std::string current_lang = settings->getLanguage();
    if (current_lang.empty()) current_lang = "en";
    
    s_language_index = 0;
    int idx = 0;
    for (const auto& lang : languages) {
        if (lang.first == current_lang) {
            s_language_index = idx;
            break;
        }
        idx++;
    }
    
    s_initialized = true;
}

// Save UI state to settings
static void saveSettingsFromUI(config::Settings* settings) {
    if (!settings) return;
    
    settings->setTheme(settings->getSkinId()); // Theme now synced with skin
    settings->setSaveZtxs(s_save_ztxs);
    settings->setAllowCustomFees(s_allow_custom_fees);
    settings->setAutoShield(s_auto_shield);
    settings->setFetchPrices(s_fetch_prices);
    settings->setUseTor(s_use_tor);
    settings->setTxExplorerUrl(s_tx_explorer);
    settings->setAddressExplorerUrl(s_addr_explorer);
    
    // Save language
    auto& i18n = util::I18n::instance();
    const auto& languages = i18n.getAvailableLanguages();
    auto it = languages.begin();
    std::advance(it, s_language_index);
    if (it != languages.end()) {
        settings->setLanguage(it->first);
    }

    // Save acrylic / visual effects settings
    settings->setAcrylicEnabled(s_acrylic_enabled);
    settings->setAcrylicQuality(s_blur_amount > 0.001f ? static_cast<int>(effects::AcrylicQuality::Low) : static_cast<int>(effects::AcrylicQuality::Off));
    settings->setBlurMultiplier(s_blur_amount);
    settings->setReducedTransparency(s_reduced_transparency);
    settings->setNoiseOpacity(s_noise_opacity);
    settings->setGradientBackground(s_gradient_background);
    
    settings->save();
}

void RenderSettingsWindow(App* app, bool* p_open)
{
    // Load settings on first open
    if (!s_initialized && app->settings()) {
        loadSettingsToUI(app->settings());
        // Initialize acrylic settings from current state
        s_acrylic_enabled = effects::ImGuiAcrylic::IsEnabled();
        s_blur_amount = effects::ImGuiAcrylic::GetBlurMultiplier();
        s_noise_opacity = effects::ImGuiAcrylic::GetNoiseOpacity();
        s_reduced_transparency = effects::ImGuiAcrylic::GetReducedTransparency();
        s_gradient_background = schema::SkinManager::instance().isGradientMode();
    }
    
    auto& S = schema::UI();
    auto win = S.window("dialogs.settings");
    auto lbl = S.label("dialogs.settings", "label");
    auto cmb = S.combo("dialogs.settings", "combo");
    auto connLbl = S.label("dialogs.settings", "connection-label");
    auto portInput = S.input("dialogs.settings", "port-input");
    auto walletBtn = S.button("dialogs.settings", "wallet-button");
    auto saveBtn = S.button("dialogs.settings", "save-button");
    auto cancelBtn = S.button("dialogs.settings", "cancel-button");
    
    if (!material::BeginOverlayDialog(TR("settings"), p_open, win.width, 0.94f)) {
        return;
    }

    if (ImGui::BeginTabBar("SettingsTabs")) {
        // General settings tab
        if (ImGui::BeginTabItem(TR("general"))) {
            ImGui::Spacing();
            
            // Skin/theme selection
            ImGui::Text("%s", TR("theme"));
            ImGui::SameLine(lbl.position);
            
            // Active skin combo (populated from SkinManager)
            auto& skinMgr = schema::SkinManager::instance();
            const auto& skins = skinMgr.available();

            // Find active skin for preview text
            std::string active_preview = "DragonX";
            bool active_is_custom = false;
            for (const auto& skin : skins) {
                if (skin.id == skinMgr.activeSkinId()) {
                    active_preview = skin.name;
                    active_is_custom = !skin.bundled;
                    break;
                }
            }

            ImGui::SetNextItemWidth(cmb.width);
            if (ImGui::BeginCombo("##Theme", active_preview.c_str())) {
                // Bundled themes header
                ImGui::TextDisabled("%s", TR("settings_builtin"));
                ImGui::Separator();
                for (size_t i = 0; i < skins.size(); i++) {
                    const auto& skin = skins[i];
                    if (!skin.bundled) continue;
                    bool is_selected = (skin.id == skinMgr.activeSkinId());

                    if (ImGui::Selectable(skin.name.c_str(), is_selected)) {
                        skinMgr.setActiveSkin(skin.id);
                        if (app->settings()) {
                            app->settings()->setSkinId(skin.id);
                            app->settings()->save();
                        }
                    }
                    if (is_selected) {
                        ImGui::SetItemDefaultFocus();
                    }
                }

                // Custom themes (if any)
                bool has_custom = false;
                for (const auto& skin : skins) {
                    if (!skin.bundled) { has_custom = true; break; }
                }
                if (has_custom) {
                    ImGui::Spacing();
                    ImGui::TextDisabled("%s", TR("settings_custom"));
                    ImGui::Separator();
                    for (size_t i = 0; i < skins.size(); i++) {
                        const auto& skin = skins[i];
                        if (skin.bundled) continue;
                        bool is_selected = (skin.id == skinMgr.activeSkinId());

                        if (!skin.valid) {
                            ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1.0f, 0.3f, 0.3f, 1.0f));
                            ImGui::BeginDisabled(true);
                            std::string label = skin.name + TR("swin_invalid_suffix");
                            ImGui::Selectable(label.c_str(), false);
                            ImGui::EndDisabled();
                            ImGui::PopStyleColor();
                            if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) {
                                material::Tooltip("%s", skin.validationError.c_str());
                            }
                        } else {
                            std::string label = skin.name;
                            if (!skin.author.empty()) {
                                label += "  (" + skin.author + ")";
                            }
                            if (ImGui::Selectable(label.c_str(), is_selected)) {
                                skinMgr.setActiveSkin(skin.id);
                                if (app->settings()) {
                                    app->settings()->setSkinId(skin.id);
                                    app->settings()->save();
                                }
                            }
                            if (is_selected) {
                                ImGui::SetItemDefaultFocus();
                            }
                        }
                    }
                }
                ImGui::EndCombo();
            }
            if (ImGui::IsItemHovered())
                material::Tooltip("%s", TR("tt_theme_hotkey"));

            // Show indicator if custom theme is active
            if (active_is_custom) {
                ImGui::SameLine();
                ImGui::PushFont(material::Type().iconSmall());
                ImGui::TextColored(ImVec4(0.4f, 0.8f, 1.0f, 1.0f), ICON_CUSTOM_THEME);
                ImGui::PopFont();
                if (ImGui::IsItemHovered()) {
                    material::Tooltip("%s", TR("tt_custom_theme"));
                }
            }

            ImGui::SameLine();
            ImGui::PushFont(material::Type().iconSmall());
            if (material::StyledButton(ICON_REFRESH_THEMES, ImVec2(0, 0))) {
                skinMgr.refresh();
                Notifications::instance().info(TR("swin_theme_list_refreshed"));
            }
            ImGui::PopFont();
            if (ImGui::IsItemHovered()) {
                material::Tooltip(TR("tt_scan_themes"),
                    schema::SkinManager::getUserSkinsDirectory().c_str());
            }

            ImGui::Spacing();

            // Language selection
            ImGui::Text("%s", TR("language"));
            ImGui::SameLine(lbl.position);
            auto& i18n = util::I18n::instance();
            const auto& languages = i18n.getAvailableLanguages();
            
            // Build language display names array
            std::vector<const char*> lang_names;
            lang_names.reserve(languages.size());
            for (const auto& lang : languages) {
                lang_names.push_back(lang.second.c_str()); // Display name
            }
            
            ImGui::SetNextItemWidth(cmb.width);
            if (ImGui::Combo("##Language", &s_language_index, lang_names.data(), static_cast<int>(lang_names.size()))) {
                // Get locale code from index
                auto it = languages.begin();
                std::advance(it, s_language_index);
                i18n.loadLanguage(it->first);
            }
            ImGui::TextDisabled("  %s", TR("settings_language_note"));

            ImGui::Spacing();
            ImGui::Separator();
            ImGui::Spacing();

            // Acrylic Effects settings
            ImGui::Text("%s", TR("settings_visual_effects"));
            ImGui::Spacing();

            ImGui::Text("%s", TR("settings_acrylic_level"));
            ImGui::SameLine(lbl.position);
            ImGui::SetNextItemWidth(cmb.width);
            {
                char blur_fmt[16];
                if (s_blur_amount < 0.01f)
                    snprintf(blur_fmt, sizeof(blur_fmt), "Off");
                else
                    snprintf(blur_fmt, sizeof(blur_fmt), "%.0f%%%%", s_blur_amount * 25.0f);
                if (ImGui::SliderFloat("##AcrylicBlur", &s_blur_amount, 0.0f, 4.0f, blur_fmt,
                                       ImGuiSliderFlags_AlwaysClamp)) {
                    if (s_blur_amount > 0.0f && s_blur_amount < 0.15f) s_blur_amount = 0.0f;
                    s_acrylic_enabled = (s_blur_amount > 0.001f);
                    effects::ImGuiAcrylic::ApplyBlurAmount(s_blur_amount);
                }
            }
            ImGui::TextDisabled("  %s", TR("tt_blur"));

            ImGui::Spacing();
            ImGui::Text("%s", TR("settings_noise_opacity"));
            ImGui::SameLine(lbl.position);
            ImGui::SetNextItemWidth(cmb.width);
            {
                char noise_fmt[16];
                if (s_noise_opacity < 0.01f)
                    snprintf(noise_fmt, sizeof(noise_fmt), "Off");
                else
                    snprintf(noise_fmt, sizeof(noise_fmt), "%.0f%%%%", s_noise_opacity * 100.0f);
                if (ImGui::SliderFloat("##NoiseOpacity", &s_noise_opacity, 0.0f, 1.0f, noise_fmt,
                                       ImGuiSliderFlags_AlwaysClamp)) {
                    effects::ImGuiAcrylic::SetNoiseOpacity(s_noise_opacity);
                }
            }
            ImGui::TextDisabled("  %s", TR("tt_noise"));

            ImGui::Spacing();
            
            // Accessibility: Reduced transparency
            if (ImGui::Checkbox(TrId("settings_reduce_transparency", "reduce_trans").c_str(), &s_reduced_transparency)) {
                effects::ImGuiAcrylic::SetReducedTransparency(s_reduced_transparency);
            }
            ImGui::TextDisabled("  %s", TR("settings_solid_colors_desc"));

            ImGui::Spacing();

            if (ImGui::Checkbox(TrId("simple_background", "simple_bg").c_str(), &s_gradient_background)) {
                schema::SkinManager::instance().setGradientMode(s_gradient_background);
            }
            ImGui::TextDisabled("  %s", TR("settings_gradient_desc"));

            ImGui::Spacing();
            ImGui::Separator();
            ImGui::Spacing();

            // Privacy settings
            ImGui::Text("%s", TR("settings_privacy"));
            ImGui::Spacing();

            ImGui::Checkbox(TrId("settings_save_shielded_local", "save_ztx_w").c_str(), &s_save_ztxs);
            ImGui::TextDisabled("  %s", TR("settings_save_shielded_desc"));

            ImGui::Spacing();

            ImGui::Checkbox(TrId("settings_auto_shield_funds", "auto_shld_w").c_str(), &s_auto_shield);
            ImGui::TextDisabled("  %s", TR("settings_auto_shield_desc"));

            ImGui::Spacing();

            ImGui::Checkbox(TrId("settings_use_tor_network", "tor_w").c_str(), &s_use_tor);
            ImGui::TextDisabled("  %s", TR("settings_tor_desc"));

            ImGui::Spacing();
            ImGui::Separator();
            ImGui::Spacing();

            // Other settings
            ImGui::Text("%s", TR("settings_other"));
            ImGui::Spacing();

            ImGui::Checkbox(TrId("custom_fees", "fees_w").c_str(), &s_allow_custom_fees);
            ImGui::Checkbox(TrId("fetch_prices", "prices_w").c_str(), &s_fetch_prices);

            ImGui::EndTabItem();
        }

        // Connection settings tab
        if (ImGui::BeginTabItem(TR("settings_connection"))) {
            ImGui::Spacing();
            
            ImGui::Text("%s", TR("settings_rpc_connection"));
            ImGui::TextDisabled("%s", TR("settings_configure_rpc"));
            ImGui::Spacing();
            ImGui::Separator();
            ImGui::Spacing();

            material::LabeledInputRow(TR("rpc_host"), connLbl.position, "##RPCHost",
                                      s_rpc_host, sizeof(s_rpc_host), cmb.width);

            material::LabeledInputRow(TR("rpc_port"), connLbl.position, "##RPCPort",
                                      s_rpc_port, sizeof(s_rpc_port), portInput.width);

            ImGui::Spacing();

            material::LabeledInputRow(TR("rpc_user"), connLbl.position, "##RPCUser",
                                      s_rpc_user, sizeof(s_rpc_user), cmb.width);

            material::LabeledInputRow(TR("rpc_pass"), connLbl.position, "##RPCPassword",
                                      s_rpc_password, sizeof(s_rpc_password), cmb.width, nullptr,
                                      ImGuiInputTextFlags_Password);

            ImGui::Spacing();
            ImGui::Separator();
            ImGui::Spacing();

            ImGui::TextDisabled("%s", TR("settings_rpc_note"));

            ImGui::Spacing();

            if (material::StyledButton(TR("test_connection"), ImVec2(0,0), S.resolveFont("button"))) {
                if (app->rpc()) {
                    rpc::RPCClient::TraceScope trace("Settings / Test connection");
                    app->rpc()->getInfo([](const nlohmann::json& result, const std::string& error) {
                        if (error.empty()) {
                            std::string version = result.value("version", "unknown");
                            std::string msg = std::string(TR("swin_connection_successful")) + version;
                            Notifications::instance().success(msg);
                        } else {
                            Notifications::instance().error(std::string(TR("swin_connection_failed")) + error);
                        }
                    });
                } else {
                    Notifications::instance().error(TR("swin_rpc_client_not_initialized"));
                }
            }

            ImGui::EndTabItem();
        }

        // Wallet tab
        if (ImGui::BeginTabItem(TR("wallet"))) {
            ImGui::Spacing();
            
            ImGui::Text("%s", TR("settings_wallet_maintenance"));
            ImGui::Spacing();
            ImGui::Separator();
            ImGui::Spacing();

            if (material::StyledButton(TR("rescan"), ImVec2(walletBtn.width, 0), S.resolveFont(walletBtn.font))) {
                if (app->rpc()) {
                    // Start rescan from block 0
                    app->rpc()->rescanBlockchain(0, [](const nlohmann::json& result, const std::string& error) {
                        if (error.empty()) {
                            int start = result.value("start_height", 0);
                            int end = result.value("stop_height", 0);
                            std::string msg = std::string(TR("swin_rescan_started_from_block")) + std::to_string(start) +
                                             TR("swin_rescan_to") + std::to_string(end);
                            Notifications::instance().success(msg);
                        } else {
                            Notifications::instance().error(std::string(TR("swin_rescan_failed")) + error);
                        }
                    });
                } else {
                    Notifications::instance().error(TR("swin_rpc_client_not_initialized"));
                }
            }
            ImGui::TextDisabled("  %s", TR("settings_rescan_desc"));

            ImGui::Spacing();

            static bool s_confirm_clear_ztx = false;
            if (material::StyledButton(TR("settings_clear_ztx_long"), ImVec2(walletBtn.width, 0), S.resolveFont(walletBtn.font))) {
                s_confirm_clear_ztx = true;
            }
            ImGui::TextDisabled("  %s", TR("settings_clear_ztx_desc"));
            
            // Confirmation dialog
            if (s_confirm_clear_ztx) {
                // Distinct idSuffix: this confirm renders nested inside (and the same frame as) the parent
                // settings dialog, so it must not share the default ##OverlayDialogContent key — otherwise it
                // inherits the parent's OverlayCardState (incl. the sticky overflow flag) and collides on the
                // child window id.
                if (material::BeginOverlayDialog(TR("confirm_clear_ztx_title"), &s_confirm_clear_ztx, 480.0f,
                                                 0.94f, 0.85f, "settings_clearztx")) {
                    material::DialogWarningHeader(TR("warning"), ImVec4(1.0f, 0.6f, 0.0f, 1.0f));

                    ImGui::Spacing();
                    ImGui::TextWrapped("%s", TR("confirm_clear_ztx_warning1"));
                    ImGui::Spacing();
                    ImGui::TextWrapped("%s", TR("confirm_clear_ztx_warning2"));
                    ImGui::Spacing();
                    ImGui::Separator();
                    ImGui::Spacing();

                    bool doCancel = false, doConfirm = false;
                    material::DialogConfirmFooter(TR("cancel"), TrId("clear_anyway", "clear_ztx_w").c_str(),
                                                  true, doCancel, doConfirm);
                    if (doCancel) {
                        s_confirm_clear_ztx = false;
                    }
                    if (doConfirm) {
                        std::string ztx_file = util::Platform::getDragonXDataDir() + "ztx_history.json";
                        if (util::Platform::deleteFile(ztx_file)) {
                            Notifications::instance().success(TR("swin_ztx_history_cleared"));
                        } else {
                            Notifications::instance().info(TR("swin_no_history_file_found"));
                        }
                        s_confirm_clear_ztx = false;
                    }
                    material::EndOverlayDialog();
                }
            }

            ImGui::Spacing();
            ImGui::Separator();
            ImGui::Spacing();

            ImGui::Text("%s", TR("settings_wallet_info"));
            ImGui::Spacing();

            // Get actual wallet size
            std::string wallet_path = util::Platform::getDragonXDataDir() + "wallet.dat";
            uint64_t wallet_size = util::Platform::getFileSize(wallet_path);
            if (wallet_size > 0) {
                std::string size_str = util::Platform::formatFileSize(wallet_size);
                ImGui::Text(TR("settings_wallet_file_size"), size_str.c_str());
            } else {
                ImGui::TextDisabled("%s", TR("settings_wallet_not_found"));
            }
            ImGui::Text(TR("settings_wallet_location"), wallet_path.c_str());

            ImGui::EndTabItem();
        }

        // Explorer tab
        if (ImGui::BeginTabItem(TR("explorer"))) {
            ImGui::Spacing();
            
            ImGui::Text("%s", TR("settings_block_explorer_urls"));
            ImGui::TextDisabled("%s", TR("settings_configure_explorer"));
            ImGui::Spacing();
            ImGui::Separator();
            ImGui::Spacing();

            ImGui::Text("%s", TR("transaction_url"));
            ImGui::SetNextItemWidth(-1);
            ImGui::InputText("##TxExplorer", s_tx_explorer, sizeof(s_tx_explorer));

            ImGui::Text("%s", TR("address_url"));
            ImGui::SetNextItemWidth(-1);
            ImGui::InputText("##AddrExplorer", s_addr_explorer, sizeof(s_addr_explorer));

            ImGui::Spacing();
            ImGui::TextDisabled("%s", TR("settings_explorer_hint"));

            ImGui::EndTabItem();
        }

        ImGui::EndTabBar();
    }

    ImGui::Spacing();
    ImGui::Separator();
    ImGui::Spacing();

    // Save/Cancel buttons
    if (material::StyledButton(TR("save"), ImVec2(saveBtn.width, 0), S.resolveFont(saveBtn.font))) {
        saveSettingsFromUI(app->settings());
        Notifications::instance().success(TR("swin_settings_saved"));
        *p_open = false;
    }
    ImGui::SameLine();
    if (material::StyledButton(TR("cancel"), ImVec2(cancelBtn.width, 0), S.resolveFont(cancelBtn.font))) {
        // Reload settings to revert changes
        loadSettingsToUI(app->settings());
        // Revert skin to what was active when settings opened
        if (!s_saved_skin_id.empty()) {
            schema::SkinManager::instance().setActiveSkin(s_saved_skin_id);
            if (app->settings()) {
                app->settings()->setSkinId(s_saved_skin_id);
                app->settings()->save();
            }
        }
        *p_open = false;
    }

    material::EndOverlayDialog();
}

} // namespace ui
} // namespace dragonx
