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

#pragma once

#include "../colors.h"
#include "../typography.h"
#include "../layout.h"
#include "../../schema/ui_schema.h"
#include "buttons.h"
#include "imgui.h"
#include "imgui_internal.h"

namespace dragonx {
namespace ui {
namespace material {

// ============================================================================
// Material Design Dialog Component
// ============================================================================
// Based on https://m2.material.io/components/dialogs
//
// Dialogs inform users about a task and can contain critical information,
// require decisions, or involve multiple tasks.

/**
 * @brief Dialog configuration
 */
struct DialogSpec {
    const char* title = nullptr;          // Dialog title
    float width = 560.0f;                 // Dialog width (280-560dp typical)
    float maxHeight = 0;                  // Max height (0 = auto)
    bool scrollableContent = false;       // Enable content scrolling
    bool fullWidth = false;               // Actions span full width
};

/**
 * @brief Begin a modal dialog
 * 
 * @param id Unique identifier
 * @param open Pointer to open state (will be set false when closed)
 * @param spec Dialog configuration
 * @return true if dialog is open
 */
bool BeginDialog(const char* id, bool* open, const DialogSpec& spec = DialogSpec());

/**
 * @brief End a dialog
 */
void EndDialog();

/**
 * @brief Simple dialog with just text content
 */
bool BeginDialog(const char* id, bool* open, const char* title);

/**
 * @brief Dialog content area (scrollable if configured)
 */
void BeginDialogContent();

/**
 * @brief End dialog content area
 */
void EndDialogContent();

/**
 * @brief Dialog actions area (buttons)
 */
void BeginDialogActions();

/**
 * @brief End dialog actions area
 */
void EndDialogActions();

/**
 * @brief Standard confirm dialog
 * 
 * @param id Unique identifier
 * @param open Pointer to open state
 * @param title Dialog title
 * @param message Dialog message
 * @param confirmText Confirm button text
 * @param cancelText Cancel button text (nullptr for no cancel)
 * @return 0 = still open, 1 = confirmed, -1 = cancelled
 */
int ConfirmDialog(const char* id, bool* open, const char* title, const char* message,
                  const char* confirmText = "Confirm", const char* cancelText = "Cancel");

/**
 * @brief Alert dialog (single action)
 * 
 * @param id Unique identifier
 * @param open Pointer to open state
 * @param title Dialog title
 * @param message Dialog message
 * @param buttonText Button text
 * @return true when dismissed
 */
bool AlertDialog(const char* id, bool* open, const char* title, const char* message,
                 const char* buttonText = "OK");

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

// Internal state for dialog rendering
struct DialogState {
    ImVec2 contentMin;
    ImVec2 contentMax;
    float contentScrollY;
    bool scrollable;
    float width;
};

static DialogState g_currentDialog;

inline bool BeginDialog(const char* id, bool* open, const DialogSpec& spec) {
    if (!*open)
        return false;
    
    // Center dialog on screen
    ImGuiIO& io = ImGui::GetIO();
    ImVec2 center = ImVec2(io.DisplaySize.x * 0.5f, io.DisplaySize.y * 0.5f);
    ImGui::SetNextWindowPos(center, ImGuiCond_Always, ImVec2(0.5f, 0.5f));
    
    // Set dialog size
    float dialogWidth = spec.width;
    ImGui::SetNextWindowSizeConstraints(
        ImVec2(280.0f, 0),  // Min size
        ImVec2(dialogWidth, spec.maxHeight > 0 ? spec.maxHeight : io.DisplaySize.y * 0.9f)
    );
    
    // Style dialog
    ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, size::DialogCornerRadius);
    ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0, 0));
    ImGui::PushStyleColor(ImGuiCol_WindowBg, ImGui::ColorConvertU32ToFloat4(Surface(Elevation::Dp24)));
    ImGui::PushStyleColor(ImGuiCol_PopupBg, ImGui::ColorConvertU32ToFloat4(Surface(Elevation::Dp24)));
    
    // Modal background (scrim)
    ImDrawList* bgDrawList = ImGui::GetBackgroundDrawList();
    bgDrawList->AddRectFilled(
        ImVec2(0, 0), io.DisplaySize,
        schema::UI().resolveColor("var(--scrim)", IM_COL32(0, 0, 0, (int)(0.32f * 255)))
    );
    
    // Open popup
    ImGui::OpenPopup(id);
    bool isOpen = ImGui::BeginPopupModal(id, open, 
        ImGuiWindowFlags_AlwaysAutoResize | 
        ImGuiWindowFlags_NoMove | 
        ImGuiWindowFlags_NoTitleBar);
    
    if (isOpen) {
        g_currentDialog.scrollable = spec.scrollableContent;
        g_currentDialog.width = dialogWidth;
        
        // Title
        if (spec.title) {
            ImGui::Dummy(ImVec2(0, spacing::dp(3)));  // 24dp top padding
            ImGui::SetCursorPosX(spacing::dp(3));    // 24dp left padding
            Typography::instance().text(TypeStyle::H6, spec.title);
            ImGui::Dummy(ImVec2(0, spacing::dp(2)));  // 16dp below title
        } else {
            ImGui::Dummy(ImVec2(0, spacing::dp(2)));  // 16dp top padding without title
        }
    }
    
    ImGui::PopStyleColor(2);
    ImGui::PopStyleVar(2);
    
    return isOpen;
}

inline void EndDialog() {
    ImGui::EndPopup();
}

inline bool BeginDialog(const char* id, bool* open, const char* title) {
    DialogSpec spec;
    spec.title = title;
    return BeginDialog(id, open, spec);
}

inline void BeginDialogContent() {
    ImGui::SetCursorPosX(spacing::dp(3));  // 24dp left padding
    
    // Start content region
    float maxWidth = g_currentDialog.width - spacing::dp(6);  // 24dp padding each side
    ImGui::PushTextWrapPos(ImGui::GetCursorPosX() + maxWidth);
    
    if (g_currentDialog.scrollable) {
        ImGui::BeginChild("##dialogContent", ImVec2(maxWidth, 200), false);
    }
}

inline void EndDialogContent() {
    if (g_currentDialog.scrollable) {
        ImGui::EndChild();
    }
    ImGui::PopTextWrapPos();
    ImGui::Dummy(ImVec2(0, spacing::dp(3)));  // 24dp after content
}

inline void BeginDialogActions() {
    // Actions area - right-aligned buttons with 8dp spacing
    float contentWidth = ImGui::GetContentRegionAvail().x;
    ImGui::SetCursorPosX(spacing::dp(1));  // 8dp left padding for actions
    
    // Push style for action buttons
    ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(spacing::dp(1), 0));  // 8dp between buttons
    
    // Right-align: use a dummy to push buttons right
    // Buttons will be added inline with SameLine
}

inline void EndDialogActions() {
    ImGui::PopStyleVar();
    ImGui::Dummy(ImVec2(0, spacing::dp(1)));  // 8dp bottom padding
}

inline int ConfirmDialog(const char* id, bool* open, const char* title, const char* message,
                         const char* confirmText, const char* cancelText) {
    int result = 0;
    
    if (BeginDialog(id, open, title)) {
        BeginDialogContent();
        Typography::instance().textWrapped(TypeStyle::Body1, message);
        EndDialogContent();
        
        BeginDialogActions();
        
        // Calculate button positions for right alignment
        float cancelWidth = cancelText ? ImGui::CalcTextSize(cancelText).x + spacing::dp(2) : 0;
        float confirmWidth = ImGui::CalcTextSize(confirmText).x + spacing::dp(2);
        float totalButtonWidth = cancelWidth + confirmWidth + (cancelText ? spacing::dp(1) : 0);
        float startX = ImGui::GetContentRegionAvail().x - totalButtonWidth - spacing::dp(2);
        
        ImGui::SetCursorPosX(ImGui::GetCursorPosX() + startX);
        
        if (cancelText) {
            if (TextButton(cancelText)) {
                *open = false;
                result = -1;
            }
            ImGui::SameLine();
        }
        
        if (ContainedButton(confirmText)) {
            *open = false;
            result = 1;
        }
        
        EndDialogActions();
        EndDialog();
    }
    
    return result;
}

inline bool AlertDialog(const char* id, bool* open, const char* title, const char* message,
                        const char* buttonText) {
    bool dismissed = false;
    
    if (BeginDialog(id, open, title)) {
        BeginDialogContent();
        Typography::instance().textWrapped(TypeStyle::Body1, message);
        EndDialogContent();
        
        BeginDialogActions();
        
        // Right-align single button
        float buttonWidth = ImGui::CalcTextSize(buttonText).x + spacing::dp(2);
        float startX = ImGui::GetContentRegionAvail().x - buttonWidth - spacing::dp(2);
        ImGui::SetCursorPosX(ImGui::GetCursorPosX() + startX);
        
        if (ContainedButton(buttonText)) {
            *open = false;
            dismissed = true;
        }
        
        EndDialogActions();
        EndDialog();
    }
    
    return dismissed;
}

} // namespace material
} // namespace ui
} // namespace dragonx
