#pragma once

#include <string>
#include <nlohmann/json.hpp>

using json = nlohmann::json;

namespace warfactory {

// Forward declarations
class GMap;
struct PlanetaryCore;

/**
 * @brief Interface for step-by-step world generation layers
 *
 * Enables cycle-by-cycle execution of geological, climate, and resource generation
 * phases with progress tracking and debugging capabilities.
 */
class IGenerationLayer {
public:
    virtual ~IGenerationLayer() = default;

    // ========================================
    // STEP-BY-STEP EXECUTION
    // ========================================

    /**
     * @brief Execute one step/cycle of generation
     * @param map World map to modify
     * @param core Planetary core for mass conservation
     * @param config Layer-specific configuration
     * @return true if layer has more steps to execute
     */
    virtual bool executeStep(GMap& map, PlanetaryCore& core, const json& config) = 0;

    /**
     * @brief Check if layer has more steps to execute
     * @return true if more steps available
     */
    virtual bool hasMoreSteps() const = 0;

    /**
     * @brief Reset layer to initial state
     */
    virtual void reset() = 0;

    // ========================================
    // PROGRESS TRACKING
    // ========================================

    /**
     * @brief Get current step number (0-based)
     * @return Current step index
     */
    virtual int getCurrentStep() const = 0;

    /**
     * @brief Get total number of steps in this layer
     * @return Total step count
     */
    virtual int getTotalSteps() const = 0;

    /**
     * @brief Get human-readable description of current step
     * @return Step description (e.g., "Phase 2 Cycle 15")
     */
    virtual std::string getStepDescription() const = 0;

    /**
     * @brief Get layer completion progress
     * @return Progress as percentage (0.0-1.0)
     */
    virtual float getProgress() const = 0;

    // ========================================
    // LAYER METADATA
    // ========================================

    /**
     * @brief Get layer name for identification
     * @return Layer name (e.g., "Geological", "Climate")
     */
    virtual std::string getName() const = 0;

    /**
     * @brief Get estimated time for this layer
     * @return Estimated seconds for completion
     */
    virtual float getEstimatedDuration() const = 0;

    /**
     * @brief Check if layer is currently active
     * @return true if layer is executing
     */
    virtual bool isActive() const = 0;

    /**
     * @brief Check if layer execution is complete
     * @return true if all steps finished
     */
    virtual bool isComplete() const = 0;

    // ========================================
    // CONFIGURATION AND VALIDATION
    // ========================================

    /**
     * @brief Validate configuration before execution
     * @param config Configuration JSON to validate
     * @return true if configuration is valid
     */
    virtual bool validateConfig(const json& config) const = 0;

    /**
     * @brief Get default configuration for this layer
     * @return Default JSON configuration
     */
    virtual json getDefaultConfig() const = 0;

    /**
     * @brief Get required configuration parameters
     * @return Vector of required parameter names
     */
    virtual std::vector<std::string> getRequiredConfigParams() const = 0;

    // ========================================
    // DEBUGGING AND MONITORING
    // ========================================

    /**
     * @brief Get detailed status information
     * @return JSON with current state details
     */
    virtual json getDetailedStatus() const = 0;

    /**
     * @brief Get performance metrics for this layer
     * @return JSON with timing and performance data
     */
    virtual json getPerformanceMetrics() const = 0;

    /**
     * @brief Enable/disable detailed logging
     * @param enabled Whether to enable verbose logging
     */
    virtual void setVerboseLogging(bool enabled) = 0;

    /**
     * @brief Check if layer can be paused mid-execution
     * @return true if pausable
     */
    virtual bool isPausable() const = 0;

    /**
     * @brief Pause layer execution
     */
    virtual void pause() = 0;

    /**
     * @brief Resume layer execution
     */
    virtual void resume() = 0;
};

/**
 * @brief Base implementation with common functionality
 *
 * Provides standard implementations for common layer operations.
 * Derived layers only need to implement generation-specific logic.
 */
class GenerationLayerBase : public IGenerationLayer {
protected:
    // State tracking
    int current_step = 0;
    int total_steps = 0;
    bool active = false;
    bool complete = false;
    bool paused = false;
    bool verbose_logging = false;

    // Performance tracking
    mutable float execution_time = 0.0f;
    mutable int steps_executed = 0;

    // Layer metadata
    std::string layer_name;
    float estimated_duration = 0.0f;

public:
    /**
     * @brief Constructor
     * @param name Layer name
     * @param steps Total number of steps
     * @param duration Estimated duration in seconds
     */
    GenerationLayerBase(const std::string& name, int steps, float duration);

    // ========================================
    // COMMON IMPLEMENTATIONS
    // ========================================

    float getProgress() const override;
    std::string getName() const override { return layer_name; }
    float getEstimatedDuration() const override { return estimated_duration; }
    bool isActive() const override { return active; }
    bool isComplete() const override { return complete; }
    int getCurrentStep() const override { return current_step; }
    int getTotalSteps() const override { return total_steps; }

    void reset() override;
    void pause() override { paused = true; }
    void resume() override { paused = false; }
    bool isPausable() const override { return true; }
    void setVerboseLogging(bool enabled) override { verbose_logging = enabled; }

    json getPerformanceMetrics() const override;
    json getDetailedStatus() const override;

    // ========================================
    // TO BE IMPLEMENTED BY DERIVED CLASSES
    // ========================================

    virtual bool executeStep(GMap& map, PlanetaryCore& core, const json& config) override = 0;
    virtual std::string getStepDescription() const override = 0;
    virtual bool validateConfig(const json& config) const override = 0;
    virtual json getDefaultConfig() const override = 0;
    virtual std::vector<std::string> getRequiredConfigParams() const override = 0;

protected:
    /**
     * @brief Mark step as complete and advance
     * @return true if more steps available
     */
    bool advanceStep();

    /**
     * @brief Mark layer as complete
     */
    void markComplete();

    /**
     * @brief Log message if verbose logging enabled
     * @param message Message to log
     */
    void logVerbose(const std::string& message) const;
};

} // namespace warfactory