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

#include "validate_address_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 "../theme.h"
#include "imgui.h"

namespace dragonx {
namespace ui {

// Static member initialization
bool ValidateAddressDialog::s_open = false;
bool ValidateAddressDialog::s_validated = false;
bool ValidateAddressDialog::s_validating = false;
char ValidateAddressDialog::s_address_input[512] = "";
bool ValidateAddressDialog::s_is_valid = false;
bool ValidateAddressDialog::s_is_mine = false;
std::string ValidateAddressDialog::s_address_type;
std::string ValidateAddressDialog::s_error_message;

void ValidateAddressDialog::show()
{
    s_open = true;
    s_validated = false;
    s_validating = false;
    s_address_input[0] = '\0';
    s_is_valid = false;
    s_is_mine = false;
    s_address_type.clear();
    s_error_message.clear();
}

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

void ValidateAddressDialog::hide()
{
    s_open = false;
}

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

    auto& S = schema::UI();
    auto win = S.window("dialogs.validate-address");
    auto valBtn = S.button("dialogs.validate-address", "validate-button");
    auto pasteBtn = S.button("dialogs.validate-address", "paste-button");
    auto lbl = S.label("dialogs.validate-address", "label");
    auto closeBtn = S.button("dialogs.validate-address", "close-button");

    material::OverlayDialogSpec ov;
    ov.title = TR("validate_title"); ov.p_open = &s_open;
    ov.style = material::OverlayStyle::BlurFloat;
    ov.cardWidth = win.width; ov.idSuffix = "validateaddr";
    if (material::BeginOverlayDialog(ov)) {
        ImGui::TextWrapped("%s", TR("validate_description"));

        ImGui::Spacing();

        // Address input
        bool enter_pressed = material::LabeledInput(TR("address_label"), "##ValidateAddr", s_address_input,
                                                    sizeof(s_address_input), -1.0f, nullptr,
                                                    ImGuiInputTextFlags_EnterReturnsTrue);
        
        ImGui::Spacing();
        
        // Validate button
        bool can_validate = strlen(s_address_input) > 0 && !s_validating && app->isConnected();
        
        if (!can_validate) {
            ImGui::BeginDisabled();
        }
        
        if (material::TactileButton(TR("validate_btn"), ImVec2(valBtn.width, 0), S.resolveFont(valBtn.font)) || (enter_pressed && can_validate)) {
            s_validating = true;
            s_validated = false;
            s_error_message.clear();
            
            std::string address(s_address_input);
            // Trim whitespace/newlines a pasted address often carries (the daemon would reject it).
            while (!address.empty() && (address.front()==' '||address.front()=='\t'||address.front()=='\n'||address.front()=='\r')) address.erase(address.begin());
            while (!address.empty() && (address.back()==' '||address.back()=='\t'||address.back()=='\n'||address.back()=='\r')) address.pop_back();

            // Determine if z-address or t-address
            bool is_zaddr = !address.empty() && address[0] == 'z';
            
            if (is_zaddr) {
                if (app->worker()) {
                    app->worker()->post([rpc = app->rpc(), address]() -> rpc::RPCWorker::MainCb {
                        bool valid = false, mine = false;
                        std::string error;
                        try {
                            rpc::RPCClient::TraceScope trace("Receive tab / Validate address");
                            auto result = rpc->call("validateaddress", {address});
                            valid = result.value("isvalid", false);
                            mine = result.value("ismine", false);
                        } catch (const std::exception& e) {
                            error = e.what();
                        }
                        return [valid, mine, error]() {
                            if (error.empty()) {
                                s_is_valid = valid;
                                s_is_mine = mine;
                                s_address_type = TR("validate_shielded_type");
                            } else {
                                s_error_message = error;
                                s_is_valid = false;
                            }
                            s_validated = true;
                            s_validating = false;
                        };
                    });
                }
            } else {
                if (app->worker()) {
                    app->worker()->post([rpc = app->rpc(), address]() -> rpc::RPCWorker::MainCb {
                        bool valid = false, mine = false;
                        std::string error;
                        try {
                            rpc::RPCClient::TraceScope trace("Receive tab / Validate address");
                            auto result = rpc->call("validateaddress", {address});
                            valid = result.value("isvalid", false);
                            mine = result.value("ismine", false);
                        } catch (const std::exception& e) {
                            error = e.what();
                        }
                        return [valid, mine, error]() {
                            if (error.empty()) {
                                s_is_valid = valid;
                                s_is_mine = mine;
                                s_address_type = TR("validate_transparent_type");
                            } else {
                                s_error_message = error;
                                s_is_valid = false;
                            }
                            s_validated = true;
                            s_validating = false;
                        };
                    });
                }
            }
        }
        
        if (!can_validate) {
            ImGui::EndDisabled();
        }
        
        ImGui::SameLine();
        
        if (material::TactileButton(TR("paste"), ImVec2(pasteBtn.width, 0), S.resolveFont(pasteBtn.font))) {
            const char* clipboard = ImGui::GetClipboardText();
            if (clipboard) {
                strncpy(s_address_input, clipboard, sizeof(s_address_input) - 1);
                s_address_input[sizeof(s_address_input) - 1] = '\0';
                s_validated = false;
            }
        }
        
        if (s_validating) {
            ImGui::SameLine();
            ImGui::TextColored(ImVec4(1.0f, 1.0f, 0.0f, 1.0f), "%s", TR("validating"));
        }

        ImGui::Spacing();

        // Results
        if (s_validated) {
            ImGui::Text("%s", TR("validate_results"));
            ImGui::Spacing();
            
            if (!s_error_message.empty()) {
                ImGui::TextColored(ImVec4(1.0f, 0.3f, 0.3f, 1.0f), TR("error_format"), s_error_message.c_str());
            } else {
                // Valid/Invalid indicator
                ImGui::Text("%s", TR("validate_status"));
                ImGui::SameLine(lbl.position);
                if (s_is_valid) {
                    ImGui::TextColored(ImVec4(0.3f, 0.8f, 0.3f, 1.0f), "%s", TR("validate_valid"));
                } else {
                    ImGui::TextColored(ImVec4(1.0f, 0.3f, 0.3f, 1.0f), "%s", TR("validate_invalid"));
                }
                
                if (s_is_valid) {
                    // Address type
                    ImGui::Text("%s", TR("validate_type"));
                    ImGui::SameLine(lbl.position);
                    ImGui::Text("%s", s_address_type.c_str());
                    
                    // Is mine?
                    ImGui::Text("%s", TR("validate_ownership"));
                    ImGui::SameLine(lbl.position);
                    if (s_is_mine) {
                        ImGui::TextColored(ImVec4(0.3f, 0.8f, 0.3f, 1.0f), "%s", TR("validate_is_mine"));
                    } else {
                        ImGui::TextDisabled("%s", TR("validate_not_mine"));
                    }
                }
            }
        } else if (!app->isConnected()) {
            ImGui::TextColored(ImVec4(1.0f, 0.6f, 0.0f, 1.0f), "%s", TR("not_connected"));
        } else {
            // Pre-interaction placeholder: keeps the results area from reading as a large
            // dead gap between the Validate/Paste row and the Close button until a result exists.
            ImGui::Spacing();
            float cw = ImGui::GetContentRegionAvail().x;
            ImVec2 ts = ImGui::CalcTextSize(TR("validate_results_placeholder"));
            ImGui::SetCursorPosX(ImGui::GetCursorPosX() + (cw - ts.x) * 0.5f);
            ImGui::TextDisabled("%s", TR("validate_results_placeholder"));
        }

        // Close button at bottom — centered via the shared footer helper (no separator, matching
        // the prior hand-rolled placement).
        float button_width = closeBtn.width;
        material::BeginOverlayDialogFooter(button_width, /*drawSeparator=*/false);
        if (material::TactileButton(TR("close"), ImVec2(button_width, 0), S.resolveFont(closeBtn.font))) {
            s_open = false;
        }
        material::EndOverlayDialog();
    }
}

} // namespace ui
} // namespace dragonx
