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

#pragma once

#include "layout.h"
#include "colors.h"
#include "typography.h"

namespace dragonx {
namespace ui {
namespace material {

// ============================================================================
// App Layout Manager
// ============================================================================
// Manages the overall application layout following Material Design patterns.
//
// Usage:
//   // In your main render loop:
//   auto& layout = AppLayout::instance();
//   layout.beginFrame();
//   
//   // Render app bar
//   if (layout.beginAppBar("DragonX Wallet")) {
//       // App bar content (menu items, etc.)
//       layout.endAppBar();
//   }
//   
//   // Render navigation
//   if (layout.beginNavigation()) {
//       layout.navItem("Balance", ICON_WALLET, currentTab == 0);
//       layout.navItem("Send", ICON_SEND, currentTab == 1);
//       layout.endNavigation();
//   }
//   
//   // Render main content
//   if (layout.beginContent()) {
//       // Your content here
//       layout.endContent();
//   }
//   
//   layout.endFrame();

class AppLayout {
public:
    static AppLayout& instance() {
        static AppLayout s_instance;
        return s_instance;
    }
    
    // ========================================================================
    // Frame Management
    // ========================================================================
    
    /**
     * @brief Begin a new frame layout
     * 
     * Call this at the start of each frame before any layout calls.
     * Updates responsive breakpoints and calculates regions.
     */
    void beginFrame();
    
    /**
     * @brief End the frame layout
     */
    void endFrame();
    
    // ========================================================================
    // Layout Regions
    // ========================================================================
    
    /**
     * @brief Begin the app bar region
     * 
     * @param title App title to display
     * @param showBack Show back button (for sub-pages)
     * @return true if app bar is visible
     */
    bool beginAppBar(const char* title, bool showBack = false);
    void endAppBar();
    
    /**
     * @brief Begin the navigation region (drawer/rail/bottom)
     * 
     * @return true if navigation region is visible
     */
    bool beginNavigation();
    void endNavigation();
    
    /**
     * @brief Render a navigation item
     * 
     * @param label Item label
     * @param icon Icon glyph (can be nullptr)
     * @param selected Whether this item is currently selected
     * @return true if clicked
     */
    bool navItem(const char* label, const char* icon, bool selected);
    
    /**
     * @brief Add a navigation section divider
     * 
     * @param title Optional section title
     */
    void navSection(const char* title = nullptr);
    
    /**
     * @brief Begin the main content region
     * 
     * @return true if content region is visible
     */
    bool beginContent();
    void endContent();
    
    // ========================================================================
    // Card Helpers
    // ========================================================================
    
    /**
     * @brief Begin a Material Design card
     * 
     * @param id Unique ID for the card
     * @param layout Card layout configuration
     * @return true if card is visible
     */
    bool beginCard(const char* id, const CardLayout& layout = CardLayout());
    void endCard();
    
    // ========================================================================
    // Layout Queries
    // ========================================================================
    
    /**
     * @brief Get current breakpoint category
     */
    breakpoint::Category getBreakpoint() const { return breakpoint_; }
    
    /**
     * @brief Get current navigation style
     */
    breakpoint::NavStyle getNavStyle() const { return navStyle_; }
    
    /**
     * @brief Get content region available width
     */
    float getContentWidth() const { return contentWidth_; }
    
    /**
     * @brief Get content region available height
     */
    float getContentHeight() const { return contentHeight_; }
    
    /**
     * @brief Check if navigation drawer is expanded
     */
    bool isNavExpanded() const { return navExpanded_; }
    
    /**
     * @brief Toggle navigation drawer expansion
     */
    void toggleNav() { navExpanded_ = !navExpanded_; }
    
    /**
     * @brief Set navigation drawer expansion state
     */
    void setNavExpanded(bool expanded) { navExpanded_ = expanded; }
    
private:
    AppLayout();
    ~AppLayout() = default;
    AppLayout(const AppLayout&) = delete;
    AppLayout& operator=(const AppLayout&) = delete;
    
    // Layout state
    breakpoint::Category breakpoint_ = breakpoint::Category::Md;
    breakpoint::NavStyle navStyle_ = breakpoint::NavStyle::NavDrawer;
    float windowWidth_ = 0;
    float windowHeight_ = 0;
    float contentWidth_ = 0;
    float contentHeight_ = 0;
    bool navExpanded_ = true;
    
    // Region tracking
    bool inAppBar_ = false;
    bool inNav_ = false;
    bool inContent_ = false;
    
    // Calculated regions
    ImVec2 appBarPos_;
    ImVec2 appBarSize_;
    ImVec2 navPos_;
    ImVec2 navSize_;
    ImVec2 contentPos_;
    ImVec2 contentSize_;
    
    void calculateRegions();
};

// ============================================================================
// Inline Implementation
// ============================================================================

inline AppLayout::AppLayout() {
    // Initialize with reasonable defaults
    navExpanded_ = true;
}

inline void AppLayout::beginFrame() {
    // Get main viewport size
    ImGuiViewport* viewport = ImGui::GetMainViewport();
    windowWidth_ = viewport->WorkSize.x;
    windowHeight_ = viewport->WorkSize.y;
    
    // Update responsive state
    breakpoint_ = breakpoint::GetCategory(windowWidth_);
    navStyle_ = breakpoint::GetNavStyle(breakpoint_);
    
    // Auto-collapse nav on small screens
    if (breakpoint_ == breakpoint::Category::Xs) {
        navExpanded_ = false;
    }
    
    calculateRegions();
}

inline void AppLayout::endFrame() {
    // Reset state
    inAppBar_ = false;
    inNav_ = false;
    inContent_ = false;
}

inline void AppLayout::calculateRegions() {
    // App bar at top
    appBarPos_ = ImVec2(0, 0);
    appBarSize_ = ImVec2(windowWidth_, size::AppBarHeight);
    
    float belowAppBar = size::AppBarHeight;
    float contentAreaHeight = windowHeight_ - belowAppBar;
    
    // Navigation region
    switch (navStyle_) {
        case breakpoint::NavStyle::NavDrawer:
            if (navExpanded_) {
                navSize_ = ImVec2(size::NavDrawerWidth, contentAreaHeight);
            } else {
                navSize_ = ImVec2(size::NavRailWidth, contentAreaHeight);
            }
            navPos_ = ImVec2(0, belowAppBar);
            break;
            
        case breakpoint::NavStyle::NavRail:
            navSize_ = ImVec2(size::NavRailWidth, contentAreaHeight);
            navPos_ = ImVec2(0, belowAppBar);
            break;
            
        case breakpoint::NavStyle::BottomNav:
            // Bottom nav handled separately
            navSize_ = ImVec2(windowWidth_, size::NavItemHeight);
            navPos_ = ImVec2(0, windowHeight_ - size::NavItemHeight);
            contentAreaHeight -= size::NavItemHeight;
            break;
    }
    
    // Content region
    if (navStyle_ == breakpoint::NavStyle::BottomNav) {
        contentPos_ = ImVec2(0, belowAppBar);
        contentSize_ = ImVec2(windowWidth_, contentAreaHeight);
    } else {
        contentPos_ = ImVec2(navSize_.x, belowAppBar);
        contentSize_ = ImVec2(windowWidth_ - navSize_.x, contentAreaHeight);
    }
    
    contentWidth_ = contentSize_.x;
    contentHeight_ = contentSize_.y;
}

inline bool AppLayout::beginAppBar(const char* title, bool showBack) {
    ImGui::SetNextWindowPos(appBarPos_);
    ImGui::SetNextWindowSize(appBarSize_);
    
    ImGuiWindowFlags flags = 
        ImGuiWindowFlags_NoTitleBar |
        ImGuiWindowFlags_NoResize |
        ImGuiWindowFlags_NoMove |
        ImGuiWindowFlags_NoScrollbar |
        ImGuiWindowFlags_NoCollapse |
        ImGuiWindowFlags_NoBringToFrontOnFocus;
    
    // Use elevated surface color for app bar
    ImGui::PushStyleColor(ImGuiCol_WindowBg, SurfaceVec4(4));
    ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(size::AppBarPadding, 0));
    ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0);
    
    bool visible = ImGui::Begin("##AppBar", nullptr, flags);
    
    if (visible) {
        inAppBar_ = true;
        
        // Center content vertically
        float centerY = (size::AppBarHeight - Typography::instance().getFont(TypeStyle::H6)->FontSize) * 0.5f;
        ImGui::SetCursorPosY(centerY);
        
        // Menu/back button
        if (showBack) {
            if (ImGui::Button("<")) {
                // Back action - handled by caller
            }
            ImGui::SameLine();
        } else if (navStyle_ != breakpoint::NavStyle::BottomNav) {
            // Menu button to toggle nav
            if (ImGui::Button("=")) {
                toggleNav();
            }
            ImGui::SameLine();
        }
        
        // Title
        Typography::instance().text(TypeStyle::H6, title);
    }
    
    return visible;
}

inline void AppLayout::endAppBar() {
    ImGui::End();
    ImGui::PopStyleVar(2);
    ImGui::PopStyleColor();
    inAppBar_ = false;
}

inline bool AppLayout::beginNavigation() {
    if (navStyle_ == breakpoint::NavStyle::BottomNav) {
        ImGui::SetNextWindowPos(navPos_);
    } else {
        ImGui::SetNextWindowPos(navPos_);
    }
    ImGui::SetNextWindowSize(navSize_);
    
    ImGuiWindowFlags flags = 
        ImGuiWindowFlags_NoTitleBar |
        ImGuiWindowFlags_NoResize |
        ImGuiWindowFlags_NoMove |
        ImGuiWindowFlags_NoCollapse |
        ImGuiWindowFlags_NoBringToFrontOnFocus;
    
    // Nav drawer has higher elevation
    int elevation = (navStyle_ == breakpoint::NavStyle::NavDrawer) ? 16 : 0;
    ImGui::PushStyleColor(ImGuiCol_WindowBg, SurfaceVec4(elevation));
    ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0, size::NavSectionPadding));
    ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0);
    
    bool visible = ImGui::Begin("##Navigation", nullptr, flags);
    
    if (visible) {
        inNav_ = true;
    }
    
    return visible;
}

inline void AppLayout::endNavigation() {
    ImGui::End();
    ImGui::PopStyleVar(2);
    ImGui::PopStyleColor();
    inNav_ = false;
}

inline bool AppLayout::navItem(const char* label, const char* icon, bool selected) {
    bool compact = !navExpanded_ || navStyle_ == breakpoint::NavStyle::NavRail;
    
    float itemWidth = navSize_.x;
    float itemHeight = size::NavItemHeight;
    
    ImGui::PushID(label);
    
    // Selection highlight
    if (selected) {
        ImVec2 pos = ImGui::GetCursorScreenPos();
        ImDrawList* drawList = ImGui::GetWindowDrawList();
        drawList->AddRectFilled(
            pos, 
            ImVec2(pos.x + itemWidth, pos.y + itemHeight),
            StateSelected()
        );
    }
    
    // Padding
    ImGui::SetCursorPosX(size::NavItemPadding);
    
    // Content
    bool clicked = false;
    ImGui::BeginGroup();
    
    if (compact) {
        // Rail/collapsed: Icon only, centered
        CenterHorizontally(size::IconSize);
        clicked = ImGui::Selectable(icon ? icon : "?", selected, 0, ImVec2(size::IconSize, itemHeight));
    } else {
        // Drawer: Icon + label
        if (icon) {
            ImGui::Text("%s", icon);
            ImGui::SameLine();
        }
        float selectableWidth = itemWidth - size::NavItemPadding * 2 - (icon ? size::IconSize + spacing::Sm : 0);
        clicked = ImGui::Selectable(label, selected, 0, ImVec2(selectableWidth, itemHeight));
    }
    
    ImGui::EndGroup();
    ImGui::PopID();
    
    return clicked;
}

inline void AppLayout::navSection(const char* title) {
    VSpace(1);
    
    if (title && navExpanded_) {
        ImGui::SetCursorPosX(size::NavItemPadding);
        Typography::instance().textColored(TypeStyle::Caption, OnSurfaceMedium(), title);
    }
    
    // Divider
    ImGui::Separator();
    VSpace(1);
}

inline bool AppLayout::beginContent() {
    ImGui::SetNextWindowPos(contentPos_);
    ImGui::SetNextWindowSize(contentSize_);
    
    ImGuiWindowFlags flags = 
        ImGuiWindowFlags_NoTitleBar |
        ImGuiWindowFlags_NoResize |
        ImGuiWindowFlags_NoMove |
        ImGuiWindowFlags_NoScrollbar |
        ImGuiWindowFlags_NoCollapse |
        ImGuiWindowFlags_NoBringToFrontOnFocus;
    
    ImGui::PushStyleColor(ImGuiCol_WindowBg, ImGui::ColorConvertU32ToFloat4(Background()));
    ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(spacing::Md, spacing::Md));
    ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0);
    
    bool visible = ImGui::Begin("##Content", nullptr, flags);
    
    if (visible) {
        inContent_ = true;
    }
    
    return visible;
}

inline void AppLayout::endContent() {
    ImGui::End();
    ImGui::PopStyleVar(2);
    ImGui::PopStyleColor();
    inContent_ = false;
}

inline bool AppLayout::beginCard(const char* id, const CardLayout& layout) {
    float width = layout.width > 0 ? layout.width : ImGui::GetContentRegionAvail().x;
    
    ImGui::PushID(id);
    
    // Card background
    ImGui::PushStyleColor(ImGuiCol_ChildBg, SurfaceVec4(layout.elevation));
    ImGui::PushStyleVar(ImGuiStyleVar_ChildRounding, layout.cornerRadius);
    ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(layout.padding, layout.padding));
    
    ImVec2 size(width, layout.minHeight > 0 ? layout.minHeight : 0);
    bool visible = ImGui::BeginChild(id, size, ImGuiChildFlags_AutoResizeY);
    
    return visible;
}

inline void AppLayout::endCard() {
    ImGui::EndChild();
    ImGui::PopStyleVar(2);
    ImGui::PopStyleColor();
    ImGui::PopID();
    
    // Add spacing after card
    VSpace(2);
}

// ============================================================================
// Convenience Function
// ============================================================================

/**
 * @brief Get the app layout instance
 */
inline AppLayout& Layout() {
    return AppLayout::instance();
}

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