// 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 "../../embedded/IconsMaterialDesign.h"
#include "imgui.h"
#include "imgui_internal.h"

namespace dragonx {
namespace ui {
namespace material {

// ============================================================================
// Material Design Chips Component
// ============================================================================
// Based on https://m2.material.io/components/chips
//
// Chips are compact elements that represent an input, attribute, or action.

enum class ChipType {
    Input,      // User input (deletable)
    Choice,     // Single selection from set
    Filter,     // Filter/checkbox style
    Action      // Triggers action
};

/**
 * @brief Chip configuration
 */
struct ChipSpec {
    ChipType type = ChipType::Action;
    const char* label = nullptr;
    const char* icon = nullptr;          // Leading icon
    const char* avatar = nullptr;        // Avatar text (overrides icon)
    ImU32 avatarColor = 0;               // Avatar background color
    bool selected = false;               // For choice/filter chips
    bool disabled = false;
    bool outlined = false;               // Outlined vs filled style
};

/**
 * @brief Render a chip
 * 
 * @param spec Chip configuration
 * @return For filter/choice: true if clicked (toggle selection)
 *         For input: true if delete clicked
 *         For action: true if clicked
 */
bool Chip(const ChipSpec& spec);

/**
 * @brief Simple action chip
 */
bool Chip(const char* label);

/**
 * @brief Filter chip (toggleable)
 */
bool FilterChip(const char* label, bool* selected);

/**
 * @brief Choice chip (radio-style)
 */
bool ChoiceChip(const char* label, bool selected);

/**
 * @brief Input chip with delete
 */
bool InputChip(const char* label, const char* avatar = nullptr);

/**
 * @brief Begin a chip group for layout
 */
void BeginChipGroup();

/**
 * @brief End a chip group
 */
void EndChipGroup();

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

inline bool Chip(const ChipSpec& spec) {
    ImGuiWindow* window = ImGui::GetCurrentWindow();
    if (window->SkipItems)
        return false;
    
    ImGui::PushID(spec.label);
    
    // Chip dimensions
    const float chipHeight = 32.0f;
    const float cornerRadius = chipHeight * 0.5f;
    const float horizontalPadding = 12.0f;
    const float iconSize = 18.0f;
    const float avatarSize = 24.0f;
    const float deleteIconSize = 18.0f;
    
    // Calculate content width
    float contentWidth = horizontalPadding * 2;
    
    bool hasLeading = spec.icon || spec.avatar;
    bool hasDelete = (spec.type == ChipType::Input);
    bool hasCheckmark = (spec.type == ChipType::Filter && spec.selected);
    
    if (spec.avatar) {
        contentWidth += avatarSize + 8.0f;
    } else if (spec.icon || hasCheckmark) {
        contentWidth += iconSize + 8.0f;
    }
    
    contentWidth += ImGui::CalcTextSize(spec.label).x;
    
    if (hasDelete) {
        contentWidth += deleteIconSize + 8.0f;
    }
    
    // Layout
    ImVec2 pos = window->DC.CursorPos;
    ImRect chipBB(pos, ImVec2(pos.x + contentWidth, pos.y + chipHeight));
    
    // Interaction
    ImGuiID id = window->GetID("##chip");
    ImGui::ItemSize(chipBB);
    if (!ImGui::ItemAdd(chipBB, id))
        return false;
    
    bool hovered, held;
    bool clicked = ImGui::ButtonBehavior(chipBB, id, &hovered, &held) && !spec.disabled;
    
    // Delete button hit test (for input chips)
    bool deleteClicked = false;
    if (hasDelete) {
        float deleteX = chipBB.Max.x - horizontalPadding - deleteIconSize;
        ImRect deleteBB(
            ImVec2(deleteX, pos.y + (chipHeight - deleteIconSize) * 0.5f),
            ImVec2(deleteX + deleteIconSize, pos.y + (chipHeight + deleteIconSize) * 0.5f)
        );
        
        ImGuiID deleteId = window->GetID("##delete");
        bool deleteHovered, deleteHeld;
        deleteClicked = ImGui::ButtonBehavior(deleteBB, deleteId, &deleteHovered, &deleteHeld);
    }
    
    // Draw
    ImDrawList* drawList = window->DrawList;
    
    // Background
    ImU32 bgColor;
    ImU32 borderColor = 0;
    
    if (spec.disabled) {
        bgColor = schema::UI().resolveColor("var(--surface-hover)", IM_COL32(255, 255, 255, 30));
    } else if (spec.selected) {
        bgColor = WithAlpha(Primary(), 51);    // Primary at 20%
    } else if (spec.outlined) {
        bgColor = 0;                             // Transparent
        borderColor = OnSurfaceMedium();
    } else {
        bgColor = schema::UI().resolveColor("var(--surface-hover)", IM_COL32(255, 255, 255, 30));
    }
    
    // Hover/press overlay
    if (!spec.disabled) {
        if (held) {
            bgColor = IM_COL32_ADD(bgColor, schema::UI().resolveColor("var(--hover-overlay)", IM_COL32(255, 255, 255, 25)));
        } else if (hovered) {
            bgColor = IM_COL32_ADD(bgColor, schema::UI().resolveColor("var(--active-overlay)", IM_COL32(255, 255, 255, 10)));
        }
    }
    
    // Draw background
    if (bgColor) {
        drawList->AddRectFilled(chipBB.Min, chipBB.Max, bgColor, cornerRadius);
    }
    
    // Draw border for outlined
    if (borderColor) {
        drawList->AddRect(chipBB.Min, chipBB.Max, borderColor, cornerRadius, 0, 1.0f);
    }
    
    // Content
    float currentX = pos.x + horizontalPadding;
    float centerY = pos.y + chipHeight * 0.5f;
    
    ImU32 contentColor = spec.disabled ? OnSurfaceDisabled() : OnSurface();
    ImU32 iconColor = spec.disabled ? OnSurfaceDisabled() : 
                      spec.selected ? Primary() : OnSurfaceMedium();
    
    // Avatar or icon
    if (spec.avatar) {
        // Avatar circle
        ImVec2 avatarCenter(currentX + avatarSize * 0.5f - 4.0f, centerY);
        ImU32 avatarBg = spec.avatarColor ? spec.avatarColor : Primary();
        drawList->AddCircleFilled(avatarCenter, avatarSize * 0.5f, avatarBg);
        
        // Avatar text
        ImVec2 textSize = ImGui::CalcTextSize(spec.avatar);
        ImVec2 textPos(avatarCenter.x - textSize.x * 0.5f, avatarCenter.y - textSize.y * 0.5f);
        drawList->AddText(textPos, OnPrimary(), spec.avatar);
        
        currentX += avatarSize + 4.0f;
    } else if (hasCheckmark) {
        // Checkmark for selected filter chips
        ImFont* iconFont = Typography::instance().iconSmall();
        ImVec2 chkSz = iconFont->CalcTextSizeA(iconFont->LegacySize, 1000.0f, 0.0f, ICON_MD_CHECK);
        drawList->AddText(iconFont, iconFont->LegacySize,
            ImVec2(currentX, centerY - chkSz.y * 0.5f), Primary(), ICON_MD_CHECK);
        currentX += iconSize + 4.0f;
    } else if (spec.icon) {
        drawList->AddText(ImVec2(currentX, centerY - iconSize * 0.5f), iconColor, spec.icon);
        currentX += iconSize + 4.0f;
    }
    
    // Label
    Typography::instance().pushFont(TypeStyle::Body2);
    float labelY = centerY - ImGui::GetFontSize() * 0.5f;
    drawList->AddText(ImVec2(currentX, labelY), contentColor, spec.label);
    Typography::instance().popFont();
    
    // Delete icon (for input chips)
    if (hasDelete) {
        float deleteX = chipBB.Max.x - horizontalPadding - deleteIconSize;
        ImFont* iconFont = Typography::instance().iconSmall();
        ImVec2 delSz = iconFont->CalcTextSizeA(iconFont->LegacySize, 1000.0f, 0.0f, ICON_MD_CLOSE);
        drawList->AddText(iconFont, iconFont->LegacySize,
            ImVec2(deleteX, centerY - delSz.y * 0.5f),
            OnSurfaceMedium(), ICON_MD_CLOSE
        );
    }
    
    ImGui::PopID();
    
    // Return value depends on chip type
    if (spec.type == ChipType::Input) {
        return deleteClicked;
    }
    return clicked;
}

inline bool Chip(const char* label) {
    ChipSpec spec;
    spec.label = label;
    spec.type = ChipType::Action;
    return Chip(spec);
}

inline bool FilterChip(const char* label, bool* selected) {
    ChipSpec spec;
    spec.label = label;
    spec.type = ChipType::Filter;
    spec.selected = *selected;
    
    bool clicked = Chip(spec);
    if (clicked) {
        *selected = !*selected;
    }
    return clicked;
}

inline bool ChoiceChip(const char* label, bool selected) {
    ChipSpec spec;
    spec.label = label;
    spec.type = ChipType::Choice;
    spec.selected = selected;
    return Chip(spec);
}

inline bool InputChip(const char* label, const char* avatar) {
    ChipSpec spec;
    spec.label = label;
    spec.type = ChipType::Input;
    spec.avatar = avatar;
    return Chip(spec);
}

inline void BeginChipGroup() {
    ImGui::BeginGroup();
    ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(spacing::dp(1), spacing::dp(1)));  // 8dp spacing
}

inline void EndChipGroup() {
    ImGui::PopStyleVar();
    ImGui::EndGroup();
}

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