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

#include "transaction_details_dialog.h"
#include "../../app.h"
#include "../../config/settings.h"
#include "../../util/i18n.h"
#include "../../util/platform.h"
#include "../theme.h"
#include "../schema/ui_schema.h"
#include "../material/draw_helpers.h"
#include "imgui.h"
#include <ctime>

namespace dragonx {
namespace ui {

// Static member initialization
bool TransactionDetailsDialog::s_open = false;
TransactionInfo TransactionDetailsDialog::s_transaction;

void TransactionDetailsDialog::show(const TransactionInfo& tx)
{
    s_open = true;
    s_transaction = tx;
}

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

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

    auto& S = schema::UI();
    auto win = S.window("dialogs.transaction-details");
    auto lbl = S.label("dialogs.transaction-details", "label");
    auto confLbl = S.label("dialogs.transaction-details", "confirmations-label");
    auto txidInput = S.input("dialogs.transaction-details", "txid-input");
    auto copyBtn = S.button("dialogs.transaction-details", "copy-button");
    auto addrInput = S.input("dialogs.transaction-details", "address-input");
    auto memoInput = S.input("dialogs.transaction-details", "memo-input");
    auto bottomBtn = S.button("dialogs.transaction-details", "bottom-button");

    material::OverlayDialogSpec ov;
    ov.title = TR("tx_details_title"); ov.p_open = &s_open;
    ov.style = material::OverlayStyle::BlurFloat;   // floating content on the blur, plain heading
    ov.cardWidth = win.width;                       // keep the authored width (content is laid out to it)
    ov.cardBottomViewportRatio = 0.94f;
    if (material::BeginOverlayDialog(ov)) {
        const auto& tx = s_transaction;
        
        // Type indicator with color
        ImVec4 type_color;
        std::string type_display;
        if (tx.type == "receive") {
            type_color = ImVec4(0.3f, 0.8f, 0.3f, 1.0f);
            type_display = TR("tx_received");
        } else if (tx.type == "send") {
            type_color = ImVec4(0.8f, 0.3f, 0.3f, 1.0f);
            type_display = TR("tx_sent");
        } else if (tx.type == "generate" || tx.type == "mined") {
            type_color = ImVec4(0.3f, 0.6f, 0.9f, 1.0f);
            type_display = TR("tx_mined");
        } else if (tx.type == "immature") {
            type_color = ImVec4(0.8f, 0.8f, 0.3f, 1.0f);
            type_display = TR("tx_immature");
        } else {
            type_color = ImVec4(0.7f, 0.7f, 0.7f, 1.0f);
            type_display = tx.type;
        }
        
        ImGui::TextColored(type_color, "%s", type_display.c_str());
        ImGui::SameLine(ImGui::GetWindowWidth() - confLbl.position);
        
        // Confirmations badge
        if (tx.confirmations == 0) {
            ImGui::TextColored(ImVec4(0.8f, 0.6f, 0.0f, 1.0f), "%s", TR("pending"));
        } else if (tx.confirmations < 10) {
            ImGui::TextColored(ImVec4(0.8f, 0.8f, 0.3f, 1.0f), TR("tx_confirmations"), tx.confirmations);
        } else {
            ImGui::TextColored(ImVec4(0.3f, 0.8f, 0.3f, 1.0f), TR("tx_confirmations"), tx.confirmations);
        }
        
        ImGui::Spacing();
        ImGui::Separator();
        ImGui::Spacing();

        // Amount (prominent display)
        ImGui::Text("%s", TR("amount_label"));
        ImGui::SameLine(lbl.position);
        if (tx.amount >= 0) {
            ImGui::TextColored(ImVec4(0.3f, 0.8f, 0.3f, 1.0f), "+%.8f DRGX", tx.amount);
        } else {
            ImGui::TextColored(ImVec4(0.8f, 0.3f, 0.3f, 1.0f), "%.8f DRGX", tx.amount);
        }
        
        // USD equivalent if price available
        double price_usd = app->state().market.price_usd;
        if (price_usd > 0) {
            ImGui::SameLine();
            ImGui::TextDisabled("(~$%.2f USD)", std::abs(tx.amount) * price_usd);
        }

        ImGui::Spacing();

        // Date/Time
        ImGui::Text("%s", TR("date_label"));
        ImGui::SameLine(lbl.position);
        ImGui::Text("%s", tx.getTimeString().c_str());
        
        ImGui::Spacing();
        ImGui::Separator();
        ImGui::Spacing();

        // Transaction ID
        ImGui::Text("%s", TR("tx_id_label"));
        char txid_buf[128];
        strncpy(txid_buf, tx.txid.c_str(), sizeof(txid_buf) - 1);
        txid_buf[sizeof(txid_buf) - 1] = '\0';
        ImGui::SetNextItemWidth(txidInput.width);  // negative = fill, reserving |width| px for the Copy button (a content-region margin, not raw px — must NOT be dpi-scaled)
        ImGui::InputText("##TxID", txid_buf, sizeof(txid_buf), ImGuiInputTextFlags_ReadOnly);
        ImGui::SameLine();
        if (material::StyledButton((std::string(TR("grpb_copy")) + "##TxID").c_str(), ImVec2(copyBtn.width, 0), S.resolveFont(copyBtn.font))) {
            ImGui::SetClipboardText(tx.txid.c_str());
        }

        ImGui::Spacing();

        // Address
        if (!tx.address.empty()) {
            ImGui::Text("%s", tx.type == "send" ? TR("tx_to_address") : TR("tx_from_address"));
            
            // Use multiline for z-addresses
            if (tx.address.length() > 50) {
                char addr_buf[512];
                strncpy(addr_buf, tx.address.c_str(), sizeof(addr_buf) - 1);
                addr_buf[sizeof(addr_buf) - 1] = '\0';
                // width is a negative fill-with-right-margin sentinel — keep unscaled; only height is raw px.
                ImGui::InputTextMultiline("##Address", addr_buf, sizeof(addr_buf),
                                          ImVec2(addrInput.width, (addrInput.height > 0 ? addrInput.height : 50) * Layout::dpiScale()), ImGuiInputTextFlags_ReadOnly);
            } else {
                char addr_buf[128];
                strncpy(addr_buf, tx.address.c_str(), sizeof(addr_buf) - 1);
                addr_buf[sizeof(addr_buf) - 1] = '\0';
                ImGui::SetNextItemWidth(addrInput.width);  // negative fill sentinel — must NOT be dpi-scaled
                ImGui::InputText("##Address", addr_buf, sizeof(addr_buf), ImGuiInputTextFlags_ReadOnly);
            }
            ImGui::SameLine();
            if (material::StyledButton((std::string(TR("grpb_copy")) + "##Addr").c_str(), ImVec2(copyBtn.width, 0), S.resolveFont(copyBtn.font))) {
                ImGui::SetClipboardText(tx.address.c_str());
            }
        }

        ImGui::Spacing();

        // Memo (if present)
        if (!tx.memo.empty()) {
            ImGui::Separator();
            ImGui::Spacing();
            
            ImGui::Text("%s", TR("memo_label"));
            char memo_buf[512];
            strncpy(memo_buf, tx.memo.c_str(), sizeof(memo_buf) - 1);
            memo_buf[sizeof(memo_buf) - 1] = '\0';
            ImGui::InputTextMultiline("##Memo", memo_buf, sizeof(memo_buf),
                                      ImVec2(-1, memoInput.height > 0 ? memoInput.height : 60), ImGuiInputTextFlags_ReadOnly);
        }

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

        // Buttons — centered primary + Close pair via the shared footer helper.
        // Guard against an empty/whitespace explorer URL so we never open a garbage link.
        std::string explorerBase = app->settings()->getTxExplorerUrl();
        bool explorerValid = explorerBase.find_first_not_of(" \t\r\n") != std::string::npos;
        bool doExplorer = false, doClose = false;
        material::DialogActionFooter(TR("tx_view_explorer"), explorerValid, TR("close"),
                                     doExplorer, doClose, bottomBtn.width);
        if (doExplorer) {
            std::string url = explorerBase + tx.txid;
            util::Platform::openUrl(url);
        }
        if (doClose) {
            s_open = false;
        }
        material::EndOverlayDialog();
    }
}

} // namespace ui
} // namespace dragonx
