#pragma once

#include <unordered_map>
#include <string>

namespace warfactory {

/**
 * @brief Resource-based region representing geological deposits
 *
 * Represents areas with concentrated mineral deposits from meteorite impacts,
 * volcanic activity, or geological processes. Contains specific resource types
 * and quantities suitable for mining/extraction.
 */
class ResourceRegion {
private:
    std::string name_type;                              // Resource type ("iron_ore", "coal", "oil", etc.)
    float x_position, y_position;                       // Region center coordinates
    float mass;                                         // Total mass of the deposit (tonnes)
    std::unordered_map<uint32_t, uint64_t> resources;   // Resource ID -> quantity mapping
    double formation_time;                              // When deposit was created (years)

public:
    ResourceRegion();
    ResourceRegion(const std::string& type, float x, float y, float total_mass);

    // ========================================
    // DUCK TYPING INTERFACE (Required by UniversalRegionFusionFunction)
    // ========================================

    /**
     * @brief Get region type name for fusion compatibility
     * @return Type name string (e.g., "iron_ore", "coal", "oil")
     */
    std::string getNameType() const { return name_type; }

    /**
     * @brief Get X coordinate of region center
     * @return X position in world coordinates
     */
    float getX() const { return x_position; }

    /**
     * @brief Get Y coordinate of region center
     * @return Y position in world coordinates
     */
    float getY() const { return y_position; }

    /**
     * @brief Get total mass of the resource deposit
     * @return Mass in tonnes
     */
    float getMass() const { return mass; }

    /**
     * @brief Set new position for the region
     * @param x New X coordinate
     * @param y New Y coordinate
     */
    void setPosition(float x, float y) { x_position = x; y_position = y; }

    /**
     * @brief Add mass to the region (for fusion)
     * @param additional_mass Mass to add in tonnes
     */
    void addMass(float additional_mass) { mass += additional_mass; }

    // ========================================
    // RESOURCE MANAGEMENT
    // ========================================

    /**
     * @brief Set the primary resource type for this deposit
     * @param type Resource type name
     */
    void setNameType(const std::string& type) { name_type = type; }

    /**
     * @brief Add specific resource to the deposit
     * @param resource_id Resource type ID
     * @param quantity Amount in tonnes
     */
    void addResource(uint32_t resource_id, uint64_t quantity);

    /**
     * @brief Get quantity of specific resource
     * @param resource_id Resource type ID
     * @return Quantity in tonnes (0 if not present)
     */
    uint64_t getResourceQuantity(uint32_t resource_id) const;

    /**
     * @brief Get all resources in this deposit
     * @return Map of resource ID -> quantity
     */
    const std::unordered_map<uint32_t, uint64_t>& getResources() const { return resources; }

    /**
     * @brief Remove resource from deposit (for extraction/depletion)
     * @param resource_id Resource type ID
     * @param quantity Amount to remove in tonnes
     * @return Actual amount removed (may be less if insufficient)
     */
    uint64_t removeResource(uint32_t resource_id, uint64_t quantity);

    /**
     * @brief Calculate total resource mass in deposit
     * @return Sum of all resource quantities in tonnes
     */
    uint64_t getTotalResourceMass() const;

    // ========================================
    // REGION PROPERTIES
    // ========================================

    /**
     * @brief Get formation time of this deposit
     * @return Time when deposit was created (years since world start)
     */
    double getFormationTime() const { return formation_time; }

    /**
     * @brief Set formation time
     * @param time Formation time in years
     */
    void setFormationTime(double time) { formation_time = time; }

    /**
     * @brief Check if deposit contains any resources
     * @return True if deposit has resources
     */
    bool hasResources() const { return !resources.empty(); }

    /**
     * @brief Check if deposit contains specific resource type
     * @param resource_id Resource type ID to check
     * @return True if resource is present
     */
    bool hasResource(uint32_t resource_id) const;

    /**
     * @brief Get deposit richness (resources per unit mass)
     * @return Resource density factor
     */
    float getResourceDensity() const;

    // ========================================
    // FUSION SUPPORT
    // ========================================

    /**
     * @brief Merge another resource region into this one
     * @param other ResourceRegion to merge (must be same type)
     * @return True if merge was successful
     */
    bool mergeWith(const ResourceRegion& other);

    /**
     * @brief Check if this region can merge with another
     * @param other ResourceRegion to check compatibility
     * @return True if regions are compatible for merging
     */
    bool canMergeWith(const ResourceRegion& other) const;

    /**
     * @brief Create a copy of this resource region
     * @return New ResourceRegion with same properties
     */
    ResourceRegion copy() const;

private:
    /**
     * @brief Update mass to match total resource quantities
     */
    void updateMassFromResources();

    /**
     * @brief Validate region consistency
     * @return True if region data is consistent
     */
    bool validateRegion() const;
};

} // namespace warfactory