#pragma once

#include "IModule.h"
#include "GMap.h"
#include <nlohmann/json.hpp>
#include <memory>
#include <string>
#include <vector>
#include <unordered_map>

using json = nlohmann::json;

namespace warfactory {

/**
 * @brief Feature categories based on WORLDGEN_ANALYSIS.md comprehensive analysis
 */
enum class FeatureCategory {
    // Natural geological formations
    GEOLOGICAL_FORMATIONS,      // Caves, thermal springs, salt deposits, meteorites, geysers
    GEOLOGICAL_RESOURCES,       // Basic minerals (iron, copper, coal) and precious (gold, uranium, iridium)

    // Water-related features
    AQUATIC_NATURAL,           // Lakes, ponds, river deltas, fjords, waterfalls, springs
    AQUATIC_SPECIAL,           // Marshlands, dried lakes, geysers, mountain oases

    // Land formations
    TERRESTRIAL_LANDFORMS,     // Canyons, plateaus, valleys, plains, dunes, glaciers
    TERRESTRIAL_SPECIAL,       // Oases, mountain passes, craters, calderas, badlands

    // Coastal and maritime
    COASTAL_NATURAL,           // Protected bays, cliffs, beaches, coral reefs, estuaries
    COASTAL_FORMATIONS,        // Peninsulas, straits, coastal islands, rifts

    // Historical industrial sites
    INDUSTRIAL_ABANDONED,      // Terikons, ghost towns, textile mills, power plants, steelworks
    INDUSTRIAL_CHEMICAL,       // Refineries, chemical complexes, distilleries, glass works

    // Vehicle graveyards and scrap sites
    VEHICLE_GRAVEYARDS,        // Tank, car, plane, train, boat cemeteries, electronic dumps
    SCRAP_SITES,              // Open-air dumps, service stations, electronic waste

    // Abandoned military installations
    MILITARY_COLD_WAR,        // Cold War bases, missile sites, naval bases, airfields
    MILITARY_HISTORICAL,      // WWI sites, Nazi bunkers, inactive minefields, munition depots

    // Cultural and archaeological
    CULTURAL_ANCIENT,         // Ancient ruins, medieval vestiges, archaeological sites
    CULTURAL_HISTORICAL,      // Historical monuments, cultural landmarks

    // Natural ecosystems and biomes
    BIOMES_FOREST,            // Dense forests, boreal forests, tropical rainforests
    BIOMES_GRASSLAND,         // Steppes, pampas, prairies, savannas
    BIOMES_EXTREME,           // Deserts, arctic tundra, volcanic areas, wetlands

    // Geological anomalies and special formations
    GEOLOGICAL_ANOMALIES,     // Magnetic anomalies, monoliths, radio silence zones
    GEOLOGICAL_EXTREME,       // Active fault lines, karst formations, amber deposits

    // Climate and weather phenomena
    CLIMATE_PHENOMENA,        // Cloud forests, chaparral, permafrost zones
    WEATHER_PATTERNS,         // Microclimate zones, wind corridors

    // Modern infrastructure (abandoned or ruins)
    INFRASTRUCTURE_TRANSPORT, // Abandoned roads, rail lines, bridges, tunnels
    INFRASTRUCTURE_UTILITY,   // Power lines, communication towers, pipelines

    // Mysterious and unexplained phenomena
    MYSTERIOUS_PHENOMENA,     // Unexplained formations, anomalous zones, strange sites

    CATEGORY_COUNT = 18
};

/**
 * @brief Resource integration types within features
 */
enum class ResourceIntegrationType {
    STANDALONE_DEPOSIT,        // Pure resource patch (iron ore, copper vein)
    FEATURE_INTEGRATED,        // Resource within feature (meteorite metals, scrap in ruins)
    FEATURE_BYPRODUCT,        // Secondary resource from feature (amber inclusions)
    FEATURE_HIDDEN,           // Concealed resource requiring exploration
    FEATURE_PROCESSING        // Resource requiring processing/refinement
};

/**
 * @brief World feature with integrated resources and budget scoring
 */
struct WorldFeature {
    uint32_t feature_id;                    // Unique feature identifier
    std::string feature_type;               // Specific feature type name
    FeatureCategory category;               // Primary feature category

    // Location and extent
    int center_x, center_y;                 // Feature center coordinates
    std::vector<std::pair<int, int>> affected_tiles; // All tiles covered by feature

    // Budget system integration
    float base_budget_score;                // Base score for this feature type
    float adjusted_budget_score;            // Score adjusted for regional influences
    float calculated_budget_contribution;   // Actual contribution to tile budget

    // Resource integration
    std::vector<std::pair<uint16_t, ResourceIntegrationType>> integrated_resources;
    std::unordered_map<uint16_t, uint64_t> resource_quantities;  // Resource ID -> quantity

    // Feature properties and metadata
    json feature_properties;               // Feature-specific data
    json discovery_requirements;           // Requirements to discover/access

    // Regional and probability data
    RegionalInfluence required_influence;   // Regional influence that enables this feature
    float base_probability;                // Base generation probability
    float regional_probability_modifier;   // Regional modifier (e.g., 8× for terikons in mining zones)

    // Gameplay mechanics
    bool requires_exploration;             // True if hidden resources/properties exist
    bool modifies_terrain;                // True if feature changes terrain traversability
    bool provides_strategic_value;        // True if feature has military/strategic importance

    /**
     * @brief Convert feature to JSON representation
     */
    json toJson() const;

    /**
     * @brief Create feature from JSON data
     */
    static WorldFeature fromJson(const json& data);

    /**
     * @brief Calculate total budget contribution including all resources
     */
    float calculateTotalBudgetContribution() const;

    /**
     * @brief Get resource quantity for specific type
     */
    uint64_t getResourceQuantity(uint16_t resource_type_id) const;

    /**
     * @brief Check if feature provides specific resource
     */
    bool providesResource(uint16_t resource_type_id) const;
};

/**
 * @brief World feature placement and budget balancing module
 *
 * Implements the revolutionary budget-based feature generation system from analysis:
 * - Places 218+ feature types across 18 categories
 * - Integrates resources directly into features (meteorite metals, scrap in ruins)
 * - Implements -10 to +10 budget scoring with automatic risk/reward balancing
 * - Applies regional influences (8× terikon probability in mining zones)
 * - Manages discovery system with visible/hidden feature properties
 *
 * Configuration loaded from gameData/:
 * - MapFeatures/ - Feature type definitions and properties
 * - Ressources/ - Resource type definitions and integration patterns
 * - WorldGeneration/ - Budget scoring rules and regional influences
 * - Biomes/ - Biome-feature compatibility matrices
 */
class WorldFeatureModule : public IModule {
private:
    // Feature management
    std::vector<WorldFeature> placed_features;
    std::unordered_map<uint32_t, size_t> feature_id_to_index;
    uint32_t next_feature_id;

    // World reference and generation state
    GMap* world_map;                       // Mutable reference for budget modifications
    uint64_t feature_seed;
    bool features_generated;
    bool budget_balanced;

    // Configuration data
    std::unordered_map<std::string, json> feature_type_definitions;
    std::unordered_map<uint16_t, json> resource_type_definitions;
    std::unordered_map<FeatureCategory, std::vector<std::string>> features_by_category;

    // Budget system data
    std::unordered_map<int, float> target_budget_distribution; // Target % per score
    std::unordered_map<int, int> actual_budget_distribution;   // Actual tile count per score

    /**
     * @brief Load all feature and resource definitions from configuration
     */
    void loadFeatureDefinitions(const IDataNode& config);

    /**
     * @brief Load resource integration patterns
     */
    void loadResourceIntegrationPatterns(const IDataNode& config);

    /**
     * @brief Calculate feature placement probability for location
     */
    float calculateFeaturePlacementProbability(const std::string& feature_type, int x, int y) const;

    /**
     * @brief Place features by category with budget balancing
     */
    void placeFeatureCategory(FeatureCategory category);

    /**
     * @brief Attempt to place single feature at location
     */
    bool attemptFeaturePlacement(const std::string& feature_type, int x, int y);

    /**
     * @brief Calculate budget impact of placing feature at location
     */
    float calculateBudgetImpact(const std::string& feature_type, int x, int y) const;

    /**
     * @brief Balance tile budgets by adding/removing features
     */
    void balanceRegionBudgets();

    /**
     * @brief Check biome-feature compatibility
     */
    bool isFeatureCompatibleWithBiome(const std::string& feature_type, BiomeType biome) const;

    /**
     * @brief Generate integrated resources for feature
     */
    void generateIntegratedResources(WorldFeature& feature);

    /**
     * @brief Apply regional probability modifiers
     */
    float applyRegionalModifiers(const std::string& feature_type, int x, int y, float base_probability) const;

public:
    /**
     * @brief Constructor
     */
    WorldFeatureModule();

    /**
     * @brief Destructor
     */
    virtual ~WorldFeatureModule() = default;

    // IModule interface implementation
    void setConfiguration(const IDataNode& configNode, IIO* io, ITaskScheduler* scheduler) override;
    const IDataNode& getConfiguration() override;
    json process(const json& input) override;
    void shutdown() override;
    json getState() override;
    void setState(const json& state) override;
    json getHealthStatus() override;
    std::string getType() const override;

    /**
     * @brief Set reference to world map for feature placement
     * @param map Mutable reference to generated world map
     */
    void setWorldMap(GMap* map);

    /**
     * @brief Generate and place all features with budget balancing
     * @return JSON status with budget distribution and feature statistics
     */
    json generateFeaturesWithBudgetBalancing();

    /**
     * @brief Place features for specific category
     * @param category Feature category to place
     * @return JSON status of placement for category
     */
    json placeFeaturesForCategory(FeatureCategory category);

    /**
     * @brief Get features in region with resource information
     * @param startX Starting X coordinate
     * @param startY Starting Y coordinate
     * @param width Region width
     * @param height Region height
     * @param include_hidden Include features requiring exploration
     * @return JSON array of features with resources
     */
    json getFeaturesInRegion(int startX, int startY, int width, int height, bool include_hidden = false) const;

    /**
     * @brief Get features at specific coordinates
     * @param x World X coordinate
     * @param y World Y coordinate
     * @param include_hidden Include hidden feature properties
     * @return JSON array of features at location
     */
    json getFeaturesAt(int x, int y, bool include_hidden = false) const;

    /**
     * @brief Get features by category with resource breakdown
     * @param category Feature category to filter by
     * @return JSON array of features with integrated resource data
     */
    json getFeaturesByCategory(FeatureCategory category) const;

    /**
     * @brief Get current budget score distribution
     * @return JSON with target vs actual budget distribution
     */
    json getBudgetScoreDistribution() const;

    /**
     * @brief Check if budget is balanced according to target distribution
     * @return true if budget distribution matches targets within tolerance
     */
    bool isBudgetBalanced() const;

    /**
     * @brief Force budget rebalancing for specific region
     * @param startX Starting X coordinate
     * @param startY Starting Y coordinate
     * @param width Region width
     * @param height Region height
     * @return JSON status of rebalancing operation
     */
    json rebalanceRegionBudget(int startX, int startY, int width, int height);

    /**
     * @brief Get available feature types by category
     * @return JSON mapping of categories to available feature types
     */
    json getAvailableFeatureTypes() const;

    /**
     * @brief Get comprehensive feature and resource statistics
     * @return JSON with feature counts, resource distribution, budget analysis
     */
    json getComprehensiveStats() const;

    /**
     * @brief Set feature generation seed for deterministic results
     * @param seed New seed value
     */
    void setFeatureSeed(uint64_t seed);

    /**
     * @brief Get current feature generation seed
     * @return Current seed value
     */
    uint64_t getFeatureSeed() const;

    /**
     * @brief Check if features have been generated and budget balanced
     * @return true if complete generation finished successfully
     */
    bool isGenerationComplete() const;
};

} // namespace warfactory