#include <nlohmann/json.hpp>
#include <iostream>
#include <map>
#include <vector>
#include <string>

// Note: ImGui headers would go here in a full implementation
// For now, we'll simulate the ImGui interface for testing

using json = nlohmann::json;

namespace warfactory {

// Forward declare interfaces
class IIO;
class ITaskScheduler;

class IModule {
public:
    virtual ~IModule() = default;
    virtual void initialize(const json& config, IIO* io, ITaskScheduler* scheduler) = 0;
    virtual void process(const json& input) = 0;
    virtual void shutdown() = 0;
    virtual json getState() = 0;
    virtual void setState(const json& state) = 0;
    virtual std::string getType() const = 0;
};

/**
 * @brief ClientUI Module - User Interface for Warfactory Client
 *
 * Provides ImGui-based interface to interact with server modules.
 * Communicates with Economy and MacroEntity modules via IntraIO.
 * Hot-reloadable for rapid UI development.
 */
class ClientUIModule : public IModule {
private:
    IIO* io = nullptr;
    ITaskScheduler* taskScheduler = nullptr;
    bool initialized = false;

    // UI State
    struct UIState {
        bool show_main_window = true;
        bool show_economy_window = false;
        bool show_macroentity_window = false;
        json last_economy_data;
        json last_macroentity_data;
        std::vector<std::string> log_messages;
    };

    UIState ui_state;
    int frame_count = 0;

public:
    ClientUIModule() {
        std::cout << "🎮 ClientUI Module created - Interface Ready!" << std::endl;
    }

    virtual ~ClientUIModule() {
        std::cout << "🎮 ClientUI Module destroyed (frames: " << frame_count << ")" << std::endl;
    }

    void initialize(const json& moduleConfig, IIO* ioService, ITaskScheduler* scheduler) override {
        std::cout << "🚀 Initializing ClientUI module..." << std::endl;

        io = ioService;
        taskScheduler = scheduler;

        // Subscribe to server module responses
        if (io) {
            // Note: In real implementation, these would be actual IIO calls
            std::cout << "📨 Subscribing to server module responses:" << std::endl;
            std::cout << "   - economy:response" << std::endl;
            std::cout << "   - macroentity:response" << std::endl;
        }

        // Initialize UI state
        ui_state.log_messages.push_back("ClientUI initialized");

        initialized = true;
        std::cout << "✅ ClientUI module initialized" << std::endl;
    }

    void process(const json& input) override {
        if (!initialized) return;

        frame_count++;

        // Process incoming messages from server modules
        processServerMessages();

        // Render UI (simulated for now)
        renderUI();

        // Handle UI events
        if (!input.empty()) {
            std::string type = input.value("type", "");
            if (type == "ui_event") {
                handleUIEvent(input);
            }
            else if (type == "server_response") {
                handleServerResponse(input);
            }
        }
    }

    void shutdown() override {
        std::cout << "🛑 Shutting down ClientUI module" << std::endl;
        initialized = false;
    }

    json getState() override {
        return {
            {"frame_count", frame_count},
            {"windows_state", {
                {"main_window", ui_state.show_main_window},
                {"economy_window", ui_state.show_economy_window},
                {"macroentity_window", ui_state.show_macroentity_window}
            }},
            {"log_count", ui_state.log_messages.size()},
            {"initialized", initialized}
        };
    }

    void setState(const json& state) override {
        std::cout << "🔄 Restoring ClientUI state (hot-reload)" << std::endl;

        if (state.contains("frame_count")) {
            frame_count = state["frame_count"];
        }

        if (state.contains("windows_state")) {
            auto windows = state["windows_state"];
            ui_state.show_main_window = windows.value("main_window", true);
            ui_state.show_economy_window = windows.value("economy_window", false);
            ui_state.show_macroentity_window = windows.value("macroentity_window", false);
        }

        ui_state.log_messages.push_back("State restored via hot-reload");

        std::cout << "✅ ClientUI state restored: frame " << frame_count << std::endl;
    }

    std::string getType() const override {
        return "client-ui";
    }

private:
    void processServerMessages() {
        // In real implementation, this would pull messages from IIO
        // For now, we'll simulate processing
        if (frame_count % 100 == 0) { // Every 100 frames, simulate a message
            ui_state.log_messages.push_back("Frame " + std::to_string(frame_count) + " processed");

            // Keep log manageable
            if (ui_state.log_messages.size() > 10) {
                ui_state.log_messages.erase(ui_state.log_messages.begin());
            }
        }
    }

    void renderUI() {
        // Simulated ImGui rendering - in real implementation this would be:
        // ImGui::NewFrame();
        // renderMainWindow();
        // renderEconomyWindow();
        // renderMacroEntityWindow();
        // ImGui::Render();

        if (frame_count % 50 == 0) { // Log every 50 frames
            std::cout << "🖼️ UI Rendered - Frame " << frame_count << std::endl;
            if (ui_state.show_economy_window) {
                std::cout << "   └─ Economy window active" << std::endl;
            }
            if (ui_state.show_macroentity_window) {
                std::cout << "   └─ MacroEntity window active" << std::endl;
            }
        }
    }

    void renderMainWindow() {
        // Simulated ImGui main window
        /*
        ImGui::Begin("Warfactory Client", &ui_state.show_main_window);

        if (ImGui::Button("Get Economy Prices")) {
            requestEconomyPrices();
        }

        if (ImGui::Button("Get Companies")) {
            requestCompanies();
        }

        if (ImGui::Button("Show Economy Window")) {
            ui_state.show_economy_window = true;
        }

        if (ImGui::Button("Show MacroEntity Window")) {
            ui_state.show_macroentity_window = true;
        }

        // Display log messages
        ImGui::Text("Recent Messages:");
        for (const auto& msg : ui_state.log_messages) {
            ImGui::Text("- %s", msg.c_str());
        }

        ImGui::End();
        */
    }

    void renderEconomyWindow() {
        // Simulated economy data display
        /*
        if (ui_state.show_economy_window) {
            ImGui::Begin("Economy Data", &ui_state.show_economy_window);

            if (!ui_state.last_economy_data.empty()) {
                for (auto& [item, price] : ui_state.last_economy_data.items()) {
                    ImGui::Text("%s: %.2f€", item.c_str(), price.get<double>());
                }
            } else {
                ImGui::Text("No economy data available");
                ImGui::Text("Click 'Get Economy Prices' to fetch data");
            }

            ImGui::End();
        }
        */
    }

    void renderMacroEntityWindow() {
        // Simulated macroentity data display
        /*
        if (ui_state.show_macroentity_window) {
            ImGui::Begin("Companies & States", &ui_state.show_macroentity_window);

            if (!ui_state.last_macroentity_data.empty()) {
                ImGui::Text("Companies:");
                // Display company data from last_macroentity_data
            } else {
                ImGui::Text("No company data available");
                ImGui::Text("Click 'Get Companies' to fetch data");
            }

            ImGui::End();
        }
        */
    }

    void handleUIEvent(const json& event) {
        std::string action = event.value("action", "");

        if (action == "button_click") {
            std::string button = event.value("button", "");
            ui_state.log_messages.push_back("Button clicked: " + button);

            if (button == "get_economy_prices") {
                requestEconomyPrices();
            }
            else if (button == "get_companies") {
                requestCompanies();
            }
            else if (button == "show_economy_window") {
                ui_state.show_economy_window = true;
            }
            else if (button == "show_macroentity_window") {
                ui_state.show_macroentity_window = true;
            }
        }
    }

    void handleServerResponse(const json& response) {
        std::string source = response.value("source", "unknown");

        if (source == "economy") {
            ui_state.last_economy_data = response.value("data", json{});
            ui_state.log_messages.push_back("Economy data updated");
            std::cout << "📊 Economy data received: " << ui_state.last_economy_data.dump() << std::endl;
        }
        else if (source == "macroentity") {
            ui_state.last_macroentity_data = response.value("data", json{});
            ui_state.log_messages.push_back("MacroEntity data updated");
            std::cout << "🏢 MacroEntity data received: " << ui_state.last_macroentity_data.dump() << std::endl;
        }
    }

    void requestEconomyPrices() {
        std::cout << "📤 Requesting economy prices..." << std::endl;
        ui_state.log_messages.push_back("Requested economy prices");

        // In real implementation:
        // io->publish("economy:request", {{"type", "get_prices"}});

        // For testing, simulate the request
        json request = {
            {"type", "economy_request"},
            {"action", "get_prices"}
        };

        // Simulate response after delay (would come from economy module)
        ui_state.last_economy_data = {
            {"steel_plate", 5.2},
            {"iron_ore", 1.1},
            {"copper_wire", 2.0},
            {"coal", 0.8}
        };
    }

    void requestCompanies() {
        std::cout << "📤 Requesting companies data..." << std::endl;
        ui_state.log_messages.push_back("Requested companies data");

        // In real implementation:
        // io->publish("macroentity:request", {{"type", "get_companies"}});

        // For testing, simulate the request
        json request = {
            {"type", "macroentity_request"},
            {"action", "get_companies"}
        };

        // Simulate response
        ui_state.last_macroentity_data = {
            {"steel_corp", {{"cash", 2500000}, {"strategy", "aggressive"}}},
            {"iron_works", {{"cash", 1800000}, {"strategy", "conservative"}}},
            {"logistics_ltd", {{"cash", 1200000}, {"strategy", "opportunistic"}}}
        };
    }
};

} // namespace warfactory

// C-style export functions for dynamic loading
extern "C" {
    warfactory::IModule* create_module() {
        return new warfactory::ClientUIModule();
    }

    void destroy_module(warfactory::IModule* module) {
        delete module;
    }

    const char* get_module_type() {
        return "client-ui";
    }

    const char* get_module_version() {
        return "1.0.0";
    }
}