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

#include "backup_wallet_dialog.h"
#include "../../app.h"
#include "../../rpc/rpc_client.h"
#include "../../rpc/rpc_worker.h"
#include "../../util/i18n.h"
#include "../../util/platform.h"
#include "../notifications.h"
#include "../schema/ui_schema.h"
#include "../material/draw_helpers.h"
#include "../theme.h"
#include "imgui.h"

#include <string>
#include <ctime>
#include <fstream>
#include <filesystem>

namespace dragonx {
namespace ui {

namespace fs = std::filesystem;
using json = nlohmann::json;

// Static state
static bool s_open = false;
static char s_destination[512] = "";
static std::string s_status;
static bool s_backing_up = false;

void BackupWalletDialog::show()
{
    s_open = true;
    s_status.clear();
    s_backing_up = false;
    
    // Generate default destination with timestamp
    std::time_t now = std::time(nullptr);
    char timebuf[32];
    std::strftime(timebuf, sizeof(timebuf), "%Y%m%d_%H%M%S", std::localtime(&now));
    
    // Default to home directory
    std::string home = util::Platform::getHomeDir();
    snprintf(s_destination, sizeof(s_destination), "%s/wallet_backup_%s.dat", home.c_str(), timebuf);
}

bool BackupWalletDialog::isOpen()
{
    return s_open;
}

void BackupWalletDialog::render(App* app)
{
    if (!s_open) return;

    auto& S = schema::UI();
    auto win = S.window("dialogs.backup-wallet");
    auto backupBtn = S.button("dialogs.backup-wallet", "backup-button");
    auto closeBtn = S.button("dialogs.backup-wallet", "close-button");

    if (material::BeginOverlayDialog(TR("backup_title"), &s_open, win.width, 0.94f)) {
        ImGui::TextWrapped("%s", TR("backup_description"));
        
        ImGui::Spacing();
        ImGui::Separator();
        ImGui::Spacing();
        
        if (s_backing_up) {
            ImGui::BeginDisabled();
        }
        
        // Destination path
        ImGui::Text("%s", TR("backup_destination"));
        ImGui::SetNextItemWidth(-1);
        ImGui::InputText("##Destination", s_destination, sizeof(s_destination));
        
        ImGui::Spacing();
        
        // Show wallet.dat location
        std::string walletPath = util::Platform::getDataDir() + "/wallet.dat";
        ImGui::TextDisabled(TR("backup_source"), walletPath.c_str());
        
        // Check if source exists
        bool sourceExists = fs::exists(walletPath);
        if (!sourceExists) {
            ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1.0f, 0.4f, 0.4f, 1.0f));
            ImGui::Text("%s", TR("backup_wallet_not_found"));
            ImGui::PopStyleColor();
        }
        
        if (s_backing_up) {
            ImGui::EndDisabled();
        }
        
        ImGui::Spacing();
        ImGui::Separator();
        ImGui::Spacing();
        
        // Backup button - use RPC backupwallet
        if (s_backing_up) {
            ImGui::BeginDisabled();
        }
        
        if (material::StyledButton(TR("backup_create"), ImVec2(backupBtn.width, 0), S.resolveFont(backupBtn.font))) {
            if (strlen(s_destination) == 0) {
                Notifications::instance().warning("Please enter a destination path");
            } else if (!app->rpc() || !app->rpc()->isConnected()) {
                Notifications::instance().error("Not connected to daemon");
            } else {
                s_backing_up = true;
                s_status = "Creating backup...";
                
                // Run backup on worker thread to avoid freezing UI
                std::string dest(s_destination);
                if (app->worker()) {
                    app->worker()->post([rpc = app->rpc(), dest]() -> rpc::RPCWorker::MainCb {
                        bool success = false;
                        std::string statusMsg;
                        try {
                            rpc::RPCClient::TraceScope trace("Settings / Backup wallet");
                            rpc->call("backupwallet", json::array({dest}));
                            // Check if file was created
                            if (fs::exists(dest)) {
                                auto size = fs::file_size(dest);
                                char sizebuf[32];
                                if (size > 1024 * 1024) {
                                    snprintf(sizebuf, sizeof(sizebuf), "%.2f MB", size / (1024.0 * 1024.0));
                                } else if (size > 1024) {
                                    snprintf(sizebuf, sizeof(sizebuf), "%.2f KB", size / 1024.0);
                                } else {
                                    snprintf(sizebuf, sizeof(sizebuf), "%zu bytes", size);
                                }
                                statusMsg = std::string("Backup created successfully (") + sizebuf + ")";
                                success = true;
                            } else {
                                statusMsg = "Backup may have failed - file not found";
                            }
                        } catch (const std::exception& e) {
                            statusMsg = std::string("Backup failed: ") + e.what();
                        }
                        return [success, statusMsg]() {
                            s_status = statusMsg;
                            s_backing_up = false;
                            if (success) {
                                Notifications::instance().success(TR("backup_created"), 5.0f);
                            } else {
                                Notifications::instance().warning(statusMsg);
                            }
                        };
                    });
                }
            }
        }
        
        if (s_backing_up) {
            ImGui::EndDisabled();
            ImGui::SameLine();
            ImGui::TextDisabled("%s", TR("backup_backing_up"));
        }
        
        ImGui::SameLine();
        if (material::StyledButton(TR("close"), ImVec2(closeBtn.width, 0), S.resolveFont(closeBtn.font))) {
            s_open = false;
        }
        
        // Status
        if (!s_status.empty()) {
            ImGui::Spacing();
            ImGui::TextWrapped("%s", s_status.c_str());
        }
        
        ImGui::Spacing();
        ImGui::Separator();
        ImGui::Spacing();
        
        // Tips
        ImGui::TextDisabled("%s", TR("backup_tips"));
        ImGui::BulletText("%s", TR("backup_tip_external"));
        ImGui::BulletText("%s", TR("backup_tip_multiple"));
        ImGui::BulletText("%s", TR("backup_tip_test"));
        material::EndOverlayDialog();
    }
}

} // namespace ui
} // namespace dragonx
