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

#include "request_payment_dialog.h"
#include "../../app.h"
#include "../../util/i18n.h"
#include "../../util/payment_uri.h"
#include "../notifications.h"
#include "../schema/ui_schema.h"
#include "../widgets/qr_code.h"
#include "../widgets/copy_field.h"
#include "../material/draw_helpers.h"
#include "imgui.h"

#include <string>
#include <sstream>
#include <iomanip>

namespace dragonx {
namespace ui {

// Static state
static bool s_open = false;
static char s_address[512] = "";
static double s_amount = 0.0;
static char s_memo[512] = "";
static char s_label[128] = "";
static std::string s_payment_uri;
static uintptr_t s_qr_texture = 0;
static int s_qr_width = 0;
static int s_qr_height = 0;
static bool s_uri_dirty = true;

// Helper to build payment URI
static std::string buildPaymentUri()
{
    // Route through the shared builder so this dialog and the receive tab can't diverge on scheme/encoding.
    return dragonx::util::buildPaymentUri(s_address, s_amount, s_label, s_memo);
}

void RequestPaymentDialog::show(const std::string& address)
{
    s_open = true;
    s_amount = 0.0;
    s_memo[0] = '\0';
    s_label[0] = '\0';
    s_uri_dirty = true;
    
    if (!address.empty()) {
        strncpy(s_address, address.c_str(), sizeof(s_address) - 1);
    } else {
        s_address[0] = '\0';
    }
    
    // Free old QR texture
    if (s_qr_texture != 0) {
        FreeQRTexture(s_qr_texture);
        s_qr_texture = 0;
    }
}

void RequestPaymentDialog::hide()
{
    s_open = false;
    if (s_qr_texture != 0) {
        FreeQRTexture(s_qr_texture);
        s_qr_texture = 0;
    }
}

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

    auto& S = schema::UI();
    auto win = S.window("dialogs.request-payment");
    auto zAddrLbl = S.label("dialogs.request-payment", "z-addr-label");
    auto zAddrFrontLbl = S.label("dialogs.request-payment", "z-addr-front-label");
    auto zAddrBackLbl = S.label("dialogs.request-payment", "z-addr-back-label");
    auto tAddrLbl = S.label("dialogs.request-payment", "t-addr-label");
    auto tAddrFrontLbl = S.label("dialogs.request-payment", "t-addr-front-label");
    auto tAddrBackLbl = S.label("dialogs.request-payment", "t-addr-back-label");
    auto amountInput = S.input("dialogs.request-payment", "amount-input");
    auto memoInput = S.input("dialogs.request-payment", "memo-input");
    auto qr = S.drawElement("dialogs.request-payment", "qr-code");
    auto actionBtn = S.button("dialogs.request-payment", "action-button");

    material::OverlayDialogSpec ov;
    ov.title = TR("request_title"); ov.p_open = &s_open;
    ov.style = material::OverlayStyle::BlurFloat;
    ov.cardWidth = win.width; ov.idSuffix = "requestpay";
    if (material::BeginOverlayDialog(ov)) {
        const auto& state = app->getWalletState();

        ImGui::TextWrapped("%s", TR("request_description"));

        ImGui::Spacing();

        // Address selection
        ImGui::Text("%s", TR("request_receive_address"));
        
        std::string addr_display = s_address[0] ? s_address : TR("request_select_address");
        if (addr_display.length() > static_cast<size_t>(zAddrLbl.truncate)) {
            addr_display = addr_display.substr(0, zAddrFrontLbl.truncate) + "..." + addr_display.substr(addr_display.length() - zAddrBackLbl.truncate);
        }
        
        ImGui::SetNextItemWidth(-1);
        if (ImGui::BeginCombo("##Address", addr_display.c_str())) {
            // Z-addresses
            if (!state.z_addresses.empty()) {
                ImGui::TextDisabled("%s", TR("request_shielded_addrs"));
                for (size_t i = 0; i < state.z_addresses.size(); i++) {
                    const auto& addr = state.z_addresses[i];
                    std::string label = addr.address;
                    if (label.length() > static_cast<size_t>(zAddrLbl.truncate)) {
                        label = label.substr(0, zAddrFrontLbl.truncate) + "..." + label.substr(label.length() - zAddrBackLbl.truncate);
                    }
                    
                    if (ImGui::Selectable(label.c_str(), addr.address == s_address)) {
                        strncpy(s_address, addr.address.c_str(), sizeof(s_address) - 1);
                        s_uri_dirty = true;
                    }
                }
            }

            // T-addresses
            if (!state.t_addresses.empty()) {
                ImGui::TextDisabled("%s", TR("request_transparent_addrs"));
                for (size_t i = 0; i < state.t_addresses.size(); i++) {
                    const auto& addr = state.t_addresses[i];
                    std::string label = addr.address;
                    if (label.length() > static_cast<size_t>(tAddrLbl.truncate)) {
                        label = label.substr(0, tAddrFrontLbl.truncate) + "..." + label.substr(label.length() - tAddrBackLbl.truncate);
                    }
                    
                    if (ImGui::Selectable(label.c_str(), addr.address == s_address)) {
                        strncpy(s_address, addr.address.c_str(), sizeof(s_address) - 1);
                        s_uri_dirty = true;
                    }
                }
            }
            ImGui::EndCombo();
        }
        
        ImGui::Spacing();

        // Amount (optional)
        ImGui::Text("%s", TR("request_amount"));
        ImGui::SetNextItemWidth(amountInput.width * Layout::dpiScale());
        if (ImGui::InputDouble("##Amount", &s_amount, 0.1, 1.0, "%.8f")) {
            s_uri_dirty = true;
        }
        ImGui::SameLine();
        ImGui::TextDisabled("DRGX");
        
        ImGui::Spacing();

        // Label (optional)
        if (material::LabeledInput(TR("request_label"), "##Label", s_label, sizeof(s_label))) {
            s_uri_dirty = true;
        }
        
        ImGui::Spacing();

        // Memo (optional, only for z-addr)
        bool is_zaddr = (s_address[0] == 'z');
        if (is_zaddr) {
            if (material::LabeledInputMultiline(TR("request_memo"), "##Memo", s_memo, sizeof(s_memo),
                                                ImVec2(-1, memoInput.height > 0 ? memoInput.height : 60))) {
                s_uri_dirty = true;
            }
        } else {
            s_memo[0] = '\0';  // Clear memo for t-addr
        }

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

        // Build and display payment URI
        if (s_uri_dirty && s_address[0] != '\0') {
            s_payment_uri = buildPaymentUri();
            
            // Generate new QR code
            if (s_qr_texture != 0) {
                FreeQRTexture(s_qr_texture);
            }
            s_qr_texture = GenerateQRTexture(s_payment_uri.c_str(), &s_qr_width, &s_qr_height);
            s_uri_dirty = false;
        }

        // QR Code display
        if (s_qr_texture != 0) {
            RenderQRCode(s_qr_texture, qr.size > 0 ? qr.size : 200);
        }

        ImGui::Spacing();

        // Payment URI display
        if (!s_payment_uri.empty()) {
            ImGui::Text("%s", TR("request_payment_uri"));
            // Bordered read-only field: bounds the raw drgx: URI within a box (it horizontal-scrolls if
            // long) rather than 4-char-chunking it like an address or letting a plain field overflow.
            // The "Copy URI" button below copies the full value.
            {
                char uriBuf[2048];
                snprintf(uriBuf, sizeof(uriBuf), "%s", s_payment_uri.c_str());
                ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
                ImGui::InputText("##URI", uriBuf, sizeof(uriBuf), ImGuiInputTextFlags_ReadOnly);
            }

            ImGui::Spacing();

            // Footer buttons: size each to ITS OWN label (action-button.width is a floor, not the size)
            // so "Copy Full Address" never clips its final letter — mirrors qr_popup_dialog's per-label
            // sizing. Font metrics are already DPI-scaled, so don't multiply by dpiScale() here.
            ImFont* btnFont = S.resolveFont(actionBtn.font);
            ImGui::PushFont(btnFont);
            const float btnPad = ImGui::GetStyle().FramePadding.x * 2.0f + 12.0f;  // small margin
            float w_uri   = ImGui::CalcTextSize(TR("request_copy_uri")).x + btnPad;
            float w_addr  = ImGui::CalcTextSize(TR("copy_address")).x + btnPad;
            ImGui::PopFont();
            if (w_uri  < actionBtn.width) w_uri  = actionBtn.width;
            if (w_addr < actionBtn.width) w_addr = actionBtn.width;

            // Center the two-button copy row via the shared helper (no extra divider; the Separator
            // above already frames this region). Total = both button widths + the ItemSpacing between.
            material::BeginOverlayDialogFooter(w_uri + w_addr + ImGui::GetStyle().ItemSpacing.x, false);

            // Copy URI button
            if (material::TactileButton(TR("request_copy_uri"), ImVec2(w_uri, 0), btnFont)) {
                ImGui::SetClipboardText(s_payment_uri.c_str());
                Notifications::instance().success(TR("request_uri_copied"));
            }

            ImGui::SameLine();

            if (material::TactileButton(TR("copy_address"), ImVec2(w_addr, 0), btnFont)) {
                ImGui::SetClipboardText(s_address);
                Notifications::instance().success(TR("address_copied"));
            }
        }

        ImGui::Spacing();

        // Close button — sized to its own label with the same floor.
        {
            ImFont* btnFont = S.resolveFont(actionBtn.font);
            ImGui::PushFont(btnFont);
            const float btnPad = ImGui::GetStyle().FramePadding.x * 2.0f + 12.0f;
            float w_close = ImGui::CalcTextSize(TR("close")).x + btnPad;
            ImGui::PopFont();
            if (w_close < actionBtn.width) w_close = actionBtn.width;
            // Center the lone Close button via the shared helper (no extra divider — matches the
            // existing tight spacing above it).
            material::BeginOverlayDialogFooter(w_close, false);
            if (material::TactileButton(TR("close"), ImVec2(w_close, 0), btnFont)) {
                s_open = false;
            }
        }
        material::EndOverlayDialog();
    }
    
    // Cleanup on close
    if (!s_open && s_qr_texture != 0) {
        FreeQRTexture(s_qr_texture);
        s_qr_texture = 0;
    }
}

} // namespace ui
} // namespace dragonx
