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

#include "key_export_dialog.h"
#include "../../app.h"
#include "../../rpc/rpc_client.h"
#include "../../rpc/rpc_worker.h"
#include "../../util/i18n.h"
#include "../schema/ui_schema.h"
#include "../material/draw_helpers.h"
#include "imgui.h"

namespace dragonx {
namespace ui {

// Static member initialization
bool KeyExportDialog::s_open = false;
bool KeyExportDialog::s_fetching = false;
bool KeyExportDialog::s_show_key = false;
KeyExportDialog::KeyType KeyExportDialog::s_key_type = KeyExportDialog::KeyType::Private;
std::string KeyExportDialog::s_address;
std::string KeyExportDialog::s_key;
std::string KeyExportDialog::s_error;

void KeyExportDialog::show(const std::string& address, KeyType type)
{
    s_open = true;
    s_fetching = false;
    s_show_key = false;
    s_key_type = type;
    s_address = address;
    s_key.clear();
    s_error.clear();
}

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

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

    const char* title = (s_key_type == KeyType::Private) ? 
        TR("export_private_key") : TR("export_viewing_key");

    auto& S = schema::UI();
    auto win = S.window("dialogs.key-export");
    auto warningBox = S.drawElement("dialogs.key-export", "warning-box");
    auto addrInput = S.input("dialogs.key-export", "address-input");
    auto revealBtn = S.button("dialogs.key-export", "reveal-button");
    auto keyDisplay = S.drawElement("dialogs.key-export", "key-display");
    auto toggleBtn = S.button("dialogs.key-export", "toggle-button");
    auto copyBtn = S.button("dialogs.key-export", "copy-button");
    auto closeBtn = S.button("dialogs.key-export", "close-button");

    if (material::BeginOverlayDialog(title, &s_open, win.width, 0.94f)) {
        ImGui::Spacing();

        // Warning section with colored background
        ImGui::PushStyleColor(ImGuiCol_ChildBg, ImVec4(0.6f, 0.2f, 0.2f, 0.3f));
        ImGui::BeginChild("WarningBox", ImVec2(-1, warningBox.height > 0 ? warningBox.height : 80), true);
        
        ImGui::TextColored(ImVec4(1.0f, 0.4f, 0.4f, 1.0f), "  %s", TR("warning_upper"));
        ImGui::Spacing();
        
        if (s_key_type == KeyType::Private) {
            ImGui::TextWrapped("  %s", TR("key_export_private_warning"));
        } else {
            ImGui::TextWrapped("  %s", TR("key_export_viewing_warning"));
        }
        
        ImGui::EndChild();
        ImGui::PopStyleColor();

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

        // Address display
        ImGui::Text("%s", TR("address_label"));
        
        // Determine if it's a z-address (longer) or t-address
        bool is_zaddr = s_address.length() > 50;
        
        if (is_zaddr) {
            // Use multiline for z-addresses
            char addr_buf[512];
            strncpy(addr_buf, s_address.c_str(), sizeof(addr_buf) - 1);
            addr_buf[sizeof(addr_buf) - 1] = '\0';
            ImGui::InputTextMultiline("##Address", addr_buf, sizeof(addr_buf), 
                                       ImVec2(-1, addrInput.height > 0 ? addrInput.height : 60), ImGuiInputTextFlags_ReadOnly);
        } else {
            char addr_buf[128];
            strncpy(addr_buf, s_address.c_str(), sizeof(addr_buf) - 1);
            addr_buf[sizeof(addr_buf) - 1] = '\0';
            ImGui::SetNextItemWidth(-1);
            ImGui::InputText("##Address", addr_buf, sizeof(addr_buf), ImGuiInputTextFlags_ReadOnly);
        }

        ImGui::Spacing();

        // Key display section
        const char* key_label = (s_key_type == KeyType::Private) ? TR("key_export_private_key") : TR("key_export_viewing_key");
        ImGui::Text("%s", key_label);

        if (s_fetching) {
            ImGui::TextColored(ImVec4(1.0f, 1.0f, 0.0f, 1.0f), "%s", TR("key_export_fetching"));
        } else if (!s_error.empty()) {
            ImGui::TextColored(ImVec4(1.0f, 0.3f, 0.3f, 1.0f), TR("error_format"), s_error.c_str());
        } else if (s_key.empty()) {
            // Show button to fetch key
            if (material::StyledButton(TR("key_export_reveal"), ImVec2(revealBtn.width, 0), S.resolveFont(revealBtn.font))) {
                s_fetching = true;
                
                // Check if z-address or t-address
                bool is_zaddress = (s_address.length() > 50 || s_address[0] == 'z');
                
                if (s_key_type == KeyType::Private) {
                    // Export private key
                    std::string addr = s_address;
                    std::string method = is_zaddress ? "z_exportkey" : "dumpprivkey";
                    if (app->worker()) {
                        app->worker()->post([rpc = app->rpc(), addr, method]() -> rpc::RPCWorker::MainCb {
                            std::string key;
                            std::string error;
                            try {
                                rpc::RPCClient::TraceScope trace("Settings / Export key");
                                auto result = rpc->call(method, {addr});
                                key = result.get<std::string>();
                            } catch (const std::exception& e) {
                                error = e.what();
                            }
                            return [key, error]() {
                                if (error.empty()) {
                                    s_key = key;
                                    s_show_key = false;  // Don't show by default
                                } else {
                                    s_error = error;
                                }
                                s_fetching = false;
                            };
                        });
                    }
                } else {
                    // Export viewing key (only for z-addresses)
                    if (is_zaddress) {
                        std::string addr = s_address;
                        if (app->worker()) {
                            app->worker()->post([rpc = app->rpc(), addr]() -> rpc::RPCWorker::MainCb {
                                std::string key;
                                std::string error;
                                try {
                                    rpc::RPCClient::TraceScope trace("Settings / Export viewing key");
                                    auto result = rpc->call("z_exportviewingkey", {addr});
                                    key = result.get<std::string>();
                                } catch (const std::exception& e) {
                                    error = e.what();
                                }
                                return [key, error]() {
                                    if (error.empty()) {
                                        s_key = key;
                                        s_show_key = true;  // Viewing keys are less sensitive
                                    } else {
                                        s_error = error;
                                    }
                                    s_fetching = false;
                                };
                            });
                        }
                    } else {
                        s_error = TR("key_export_viewing_keys_zonly");
                        s_fetching = false;
                    }
                }
            }
            ImGui::SameLine();
            ImGui::TextDisabled("%s", TR("key_export_click_retrieve"));
        } else {
            // Key has been fetched - display it
            
            if (s_show_key) {
                // Show the actual key
                char key_buf[1024];
                strncpy(key_buf, s_key.c_str(), sizeof(key_buf) - 1);
                key_buf[sizeof(key_buf) - 1] = '\0';
                ImGui::InputTextMultiline("##Key", key_buf, sizeof(key_buf), 
                                           ImVec2(-1, keyDisplay.height > 0 ? keyDisplay.height : 80), ImGuiInputTextFlags_ReadOnly);
            } else {
                // Show masked
                std::string masked(s_key.length(), '*');
                char masked_buf[1024];
                strncpy(masked_buf, masked.c_str(), sizeof(masked_buf) - 1);
                masked_buf[sizeof(masked_buf) - 1] = '\0';
                ImGui::InputTextMultiline("##Key", masked_buf, sizeof(masked_buf), 
                                           ImVec2(-1, keyDisplay.height > 0 ? keyDisplay.height : 80), ImGuiInputTextFlags_ReadOnly);
            }

            // Show/Hide and Copy buttons
            ImGui::Spacing();
            
            if (material::StyledButton(s_show_key ? TR("hide") : TR("show"), ImVec2(toggleBtn.width, 0), S.resolveFont(toggleBtn.font))) {
                s_show_key = !s_show_key;
            }
            
            ImGui::SameLine();
            
            if (material::StyledButton(TR("copy_to_clipboard"), ImVec2(copyBtn.width, 0), S.resolveFont(copyBtn.font))) {
                ImGui::SetClipboardText(s_key.c_str());
                // Could add a notification here
            }
        }

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

        // Close button
        float button_width = closeBtn.width;
        float avail_width = ImGui::GetContentRegionAvail().x;
        ImGui::SetCursorPosX(ImGui::GetCursorPosX() + (avail_width - button_width) / 2.0f);
        
        if (material::StyledButton(TR("close"), ImVec2(button_width, 0), S.resolveFont(closeBtn.font))) {
            s_open = false;
            // Clear sensitive data
            s_key.clear();
            s_show_key = false;
        }

        material::EndOverlayDialog();
    }
}

} // namespace ui
} // namespace dragonx
