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

#pragma once

#include "../material/material.h"
#include "../../embedded/IconsMaterialDesign.h"
#include "imgui.h"
#include <string>
#include <vector>
#include <functional>

namespace dragonx {
namespace ui {
namespace screens {

using namespace material;

// ============================================================================
// Transactions Screen
// ============================================================================
// Display transaction history with Material list

/**
 * @brief Transaction details
 */
struct Transaction {
    std::string txid;
    std::string type;           // "sent", "received", "mined", "self"
    std::string fromAddress;
    std::string toAddress;
    double amount;
    double fee;
    std::string memo;
    std::string datetime;
    int confirmations;
    int blockHeight;
    bool isShielded;
};

/**
 * @brief Transaction filter options
 */
enum class TxFilter {
    All,
    Sent,
    Received,
    Mined
};

/**
 * @brief Transactions screen with Material list
 */
class TransactionsScreen {
public:
    void setTransactions(const std::vector<Transaction>& txns) {
        m_transactions = txns;
    }
    
    void setOnTransactionClick(std::function<void(const std::string&)> callback) {
        m_onTxClick = callback;
    }
    
    void setOnCopyTxid(std::function<void(const std::string&)> callback) {
        m_onCopyTxid = callback;
    }
    
    void setOnExport(std::function<void()> callback) {
        m_onExport = callback;
    }
    
    void render();
    
private:
    void renderFilters();
    void renderTransactionList();
    void renderTransactionItem(const Transaction& tx, int index);
    void renderTransactionDetails();
    void renderEmptyState();
    
    std::vector<Transaction> m_transactions;
    std::function<void(const std::string&)> m_onTxClick;
    std::function<void(const std::string&)> m_onCopyTxid;
    std::function<void()> m_onExport;
    
    TxFilter m_filter = TxFilter::All;
    std::string m_searchQuery;
    char m_searchBuffer[256] = {0};
    
    std::string m_selectedTxid;
    bool m_showDetails = false;
};

// ============================================================================
// Implementation
// ============================================================================

inline void TransactionsScreen::render() {
    // Title and export button
    ImGui::BeginGroup();
    {
        Typography::instance().text(TypeStyle::H5, "Transactions");
        
        ImGui::SameLine(ImGui::GetContentRegionAvail().x - 100);
        
        if (OutlinedButton("📥 EXPORT")) {
            if (m_onExport) m_onExport();
        }
    }
    ImGui::EndGroup();
    
    ImGui::Dummy(ImVec2(0, spacing::dp(2)));
    
    // Filters
    renderFilters();
    
    ImGui::Dummy(ImVec2(0, spacing::dp(2)));
    
    // Transaction list or empty state
    std::vector<Transaction> filtered;
    for (const auto& tx : m_transactions) {
        // Apply type filter
        if (m_filter != TxFilter::All) {
            if (m_filter == TxFilter::Sent && tx.type != "sent") continue;
            if (m_filter == TxFilter::Received && tx.type != "received") continue;
            if (m_filter == TxFilter::Mined && tx.type != "mined") continue;
        }
        
        // Apply search filter
        if (strlen(m_searchBuffer) > 0) {
            std::string search = m_searchBuffer;
            if (tx.txid.find(search) == std::string::npos &&
                tx.toAddress.find(search) == std::string::npos &&
                tx.fromAddress.find(search) == std::string::npos &&
                tx.memo.find(search) == std::string::npos) {
                continue;
            }
        }
        
        filtered.push_back(tx);
    }
    
    if (filtered.empty()) {
        renderEmptyState();
    } else {
        // Scrollable list
        CardSpec cardSpec;
        cardSpec.elevation = 1;
        cardSpec.padding = 0;
        
        if (BeginCard(cardSpec)) {
            BeginList("tx_list", false);
            
            for (size_t i = 0; i < filtered.size(); i++) {
                renderTransactionItem(filtered[i], static_cast<int>(i));
            }
            
            EndList();
            EndCard();
        }
    }
    
    // Details popup
    if (m_showDetails) {
        renderTransactionDetails();
    }
}

inline void TransactionsScreen::renderFilters() {
    // Search field
    TextFieldSpec searchSpec;
    searchSpec.label = "Search";
    searchSpec.placeholder = "Search by address, txid, memo...";
    searchSpec.variant = TextFieldVariant::Outlined;
    searchSpec.width = 300.0f;
    searchSpec.leadingIcon = ICON_MD_SEARCH;
    
    TextField("tx_search", m_searchBuffer, sizeof(m_searchBuffer), searchSpec);
    
    ImGui::SameLine(0, spacing::dp(3));
    
    // Filter chips
    ImGui::BeginGroup();
    {
        ChipSpec chipSpec;
        chipSpec.variant = ChipVariant::Filter;
        chipSpec.selectable = true;
        
        chipSpec.selected = (m_filter == TxFilter::All);
        if (FilterChip("All", chipSpec)) {
            m_filter = TxFilter::All;
        }
        
        ImGui::SameLine(0, spacing::dp(1));
        
        chipSpec.selected = (m_filter == TxFilter::Sent);
        if (FilterChip(ICON_MD_CALL_MADE " Sent", chipSpec)) {
            m_filter = TxFilter::Sent;
        }
        
        ImGui::SameLine(0, spacing::dp(1));
        
        chipSpec.selected = (m_filter == TxFilter::Received);
        if (FilterChip(ICON_MD_CALL_RECEIVED " Received", chipSpec)) {
            m_filter = TxFilter::Received;
        }
        
        ImGui::SameLine(0, spacing::dp(1));
        
        chipSpec.selected = (m_filter == TxFilter::Mined);
        if (FilterChip(ICON_MD_CONSTRUCTION " Mined", chipSpec)) {
            m_filter = TxFilter::Mined;
        }
    }
    ImGui::EndGroup();
}

inline void TransactionsScreen::renderTransactionItem(const Transaction& tx, int index) {
    ListItemSpec itemSpec;
    
    // Icon based on type
    if (tx.type == "received") {
        itemSpec.leadingIcon = ICON_MD_CALL_RECEIVED;
    } else if (tx.type == "sent") {
        itemSpec.leadingIcon = ICON_MD_CALL_MADE;
    } else if (tx.type == "mined") {
        itemSpec.leadingIcon = ICON_MD_CONSTRUCTION;
    } else {
        itemSpec.leadingIcon = ICON_MD_SWAP_HORIZ;  // Self transfer
    }
    
    // Amount formatting
    char amountStr[64];
    if (tx.type == "sent") {
        snprintf(amountStr, sizeof(amountStr), "-%.8f DRGX", tx.amount);
    } else {
        snprintf(amountStr, sizeof(amountStr), "+%.8f DRGX", tx.amount);
    }
    itemSpec.primaryText = amountStr;
    
    // Secondary: date + confirmations
    char secondaryStr[128];
    if (tx.confirmations == 0) {
        snprintf(secondaryStr, sizeof(secondaryStr), "%s • " ICON_MD_HOURGLASS_EMPTY " Pending", tx.datetime.c_str());
    } else if (tx.confirmations < 10) {
        snprintf(secondaryStr, sizeof(secondaryStr), "%s • %d confirmations", 
                tx.datetime.c_str(), tx.confirmations);
    } else {
        snprintf(secondaryStr, sizeof(secondaryStr), "%s • " ICON_MD_CHECK " Confirmed", tx.datetime.c_str());
    }
    itemSpec.secondaryText = secondaryStr;
    
    // Privacy indicator
    if (tx.isShielded) {
        itemSpec.trailingIcon = ICON_MD_SHIELD;
    }
    
    itemSpec.dividerBelow = true;
    
    char itemId[32];
    snprintf(itemId, sizeof(itemId), "tx_%d", index);
    ImGui::PushID(itemId);
    
    if (ListItem(itemSpec)) {
        m_selectedTxid = tx.txid;
        m_showDetails = true;
    }
    
    ImGui::PopID();
}

inline void TransactionsScreen::renderTransactionDetails() {
    // Find the selected transaction
    const Transaction* selected = nullptr;
    for (const auto& tx : m_transactions) {
        if (tx.txid == m_selectedTxid) {
            selected = &tx;
            break;
        }
    }
    
    if (!selected) {
        m_showDetails = false;
        return;
    }
    
    DialogSpec dialogSpec;
    dialogSpec.title = "Transaction Details";
    dialogSpec.maxWidth = 500.0f;
    
    DialogResult result = BeginDialog("tx_details", dialogSpec);
    
    if (result.isOpen) {
        const Transaction& tx = *selected;
        
        // Type badge
        ChipSpec chipSpec;
        chipSpec.variant = ChipVariant::Filled;
        
        if (tx.type == "received") {
            chipSpec.color = colors::Green500;
            Chip(ICON_MD_CALL_RECEIVED " Received", chipSpec);
        } else if (tx.type == "sent") {
            chipSpec.color = colors::Red500;
            Chip(ICON_MD_CALL_MADE " Sent", chipSpec);
        } else if (tx.type == "mined") {
            chipSpec.color = Secondary();
            Chip(ICON_MD_CONSTRUCTION " Mined", chipSpec);
        }
        
        if (tx.isShielded) {
            ImGui::SameLine();
            chipSpec.color = Primary();
            Chip(ICON_MD_SHIELD " Shielded", chipSpec);
        }
        
        ImGui::Dummy(ImVec2(0, spacing::dp(2)));
        
        // Amount
        Typography::instance().textColored(TypeStyle::Overline, OnSurfaceMedium(), "AMOUNT");
        char amountStr[64];
        snprintf(amountStr, sizeof(amountStr), "%.8f DRGX", tx.amount);
        Typography::instance().text(TypeStyle::H5, amountStr);
        
        ImGui::Dummy(ImVec2(0, spacing::dp(2)));
        
        // Details grid
        auto detailRow = [](const char* label, const char* value, bool canCopy = false) {
            Typography::instance().textColored(TypeStyle::Caption, OnSurfaceMedium(), label);
            Typography::instance().text(TypeStyle::Body2, value);
            ImGui::Dummy(ImVec2(0, spacing::dp(1)));
        };
        
        detailRow("DATE", tx.datetime.c_str());
        
        char confStr[32];
        if (tx.confirmations == 0) {
            snprintf(confStr, sizeof(confStr), "Pending");
        } else {
            snprintf(confStr, sizeof(confStr), "%d confirmations", tx.confirmations);
        }
        detailRow("STATUS", confStr);
        
        if (tx.blockHeight > 0) {
            char blockStr[32];
            snprintf(blockStr, sizeof(blockStr), "%d", tx.blockHeight);
            detailRow("BLOCK", blockStr);
        }
        
        char feeStr[32];
        snprintf(feeStr, sizeof(feeStr), "%.8f DRGX", tx.fee);
        detailRow("FEE", feeStr);
        
        ImGui::Dummy(ImVec2(0, spacing::dp(1)));
        
        // Transaction ID
        Typography::instance().textColored(TypeStyle::Caption, OnSurfaceMedium(), "TRANSACTION ID");
        ImGui::TextWrapped("%s", tx.txid.c_str());
        
        if (TextButton(ICON_MD_CONTENT_COPY " COPY TXID")) {
            if (m_onCopyTxid) m_onCopyTxid(tx.txid);
        }
        
        // Memo if present
        if (!tx.memo.empty()) {
            ImGui::Dummy(ImVec2(0, spacing::dp(2)));
            Typography::instance().textColored(TypeStyle::Caption, OnSurfaceMedium(), "MEMO");
            ImGui::TextWrapped("%s", tx.memo.c_str());
        }
        
        ImGui::Dummy(ImVec2(0, spacing::dp(3)));
        
        // Close button
        float availWidth = ImGui::GetContentRegionAvail().x;
        ImGui::SetCursorPosX(ImGui::GetCursorPosX() + availWidth - 100);
        
        if (ContainedButton("CLOSE")) {
            m_showDetails = false;
        }
        
        EndDialog();
    }
    
    if (result.dismissed) {
        m_showDetails = false;
    }
}

inline void TransactionsScreen::renderEmptyState() {
    CardSpec cardSpec;
    cardSpec.elevation = 1;
    cardSpec.padding = spacing::dp(6);
    
    if (BeginCard(cardSpec)) {
        float availWidth = ImGui::GetContentRegionAvail().x;
        
        // Icon
        const char* icon = ICON_MD_RECEIPT;
        ImVec2 iconSize = ImGui::CalcTextSize(icon);
        ImGui::SetCursorPosX(ImGui::GetCursorPosX() + (availWidth - iconSize.x) * 0.5f);
        Typography::instance().text(TypeStyle::H3, icon);
        
        ImGui::Dummy(ImVec2(0, spacing::dp(2)));
        
        // Message
        const char* message = m_filter == TxFilter::All ? 
            "No transactions yet" : "No matching transactions";
        ImVec2 textSize = ImGui::CalcTextSize(message);
        ImGui::SetCursorPosX(ImGui::GetCursorPosX() + (availWidth - textSize.x) * 0.5f);
        Typography::instance().textColored(TypeStyle::Body1, OnSurfaceMedium(), message);
        
        EndCard();
    }
}

} // namespace screens
} // namespace ui
} // namespace dragonx
