#pragma once

#include "warfactory/ASerializable.h"
#include <map>
#include <vector>
#include <string>

namespace warfactory {

/**
 * @brief Represents the planetary core with geological properties
 *
 * Manages core temperature, composition, and geological processes that affect
 * resource availability and volcanic activity during world generation.
 */
class PlanetaryCore : public ASerializable {
private:
    float core_temperature;        // Core temperature in Celsius
    float core_pressure;          // Core pressure in GPa
    std::map<uint32_t, __uint128_t> core_composition; // Element ID -> tonnes (planetary scale)
    float mantle_temperature;     // Mantle temperature in Celsius
    float volcanic_activity_level; // 0.0 to 1.0
    float geological_age;         // Age in millions of years
    double last_impact_time;      // Last major impact time in years
    __uint128_t total_impact_energy_joules; // Cumulative impact energy in Joules

public:
    PlanetaryCore();
    PlanetaryCore(float temp, float pressure, const std::map<uint32_t, __uint128_t>& composition);

    // ========================================
    // CORE PROPERTIES
    // ========================================

    float getCoreTemperature() const { return core_temperature; }
    void setCoreTemperature(float temperature);

    float getCorePressure() const { return core_pressure; }
    void setCorePressure(float pressure) { core_pressure = pressure; }

    float getMantleTemperature() const { return mantle_temperature; }
    float getVolcanicActivityLevel() const { return volcanic_activity_level; }
    float getGeologicalAge() const { return geological_age; }

    __uint128_t getTotalImpactEnergyJoules() const { return total_impact_energy_joules; }
    double getLastImpactTime() const { return last_impact_time; }

    const std::map<uint32_t, __uint128_t>& getCoreComposition() const { return core_composition; }
    void addCoreComposition(uint32_t element_id, __uint128_t quantity);
    __uint128_t getCoreComposition(uint32_t element_id) const;

    // ========================================
    // IMPACT EFFECTS
    // ========================================

    /**
     * @brief Receive and accumulate energy from meteorite impacts
     * @param energy_joules Kinetic energy from impact in Joules (0.5 * mass * velocity²)
     * @param impact_time Time of impact in years since world start
     */
    void receiveImpactEnergy(__uint128_t energy_joules, double impact_time);

    /**
     * @brief Process natural cooling of planetary core over geological time
     * Uses realistic cooling rate based on:
     * - Current core temperature (hotter = cools faster, Stefan-Boltzmann law)
     * - Core pressure (higher = thicker crust = better insulation = slower cooling)
     * @param time_step_millions_years Duration of cooling period in millions of years
     */
    void processGeologicalCooling(float time_step_millions_years);

    /**
     * @brief Convert accumulated impact energy to temperature increase
     * Uses thermodynamic formula: ΔT = Energy / (mass × specific_heat_capacity)
     * @param energy_joules Impact energy in Joules
     * @return Temperature increase in Celsius that would be added to base core temperature
     */
    float convertImpactEnergyToHeat(__uint128_t energy_joules) const;

    // ========================================
    // RESOURCE GENERATION
    // ========================================

    std::vector<uint32_t> getAvailableResources() const;
    __uint128_t getResourceAbundance(uint32_t resource_id) const;

    // ========================================
    // SERIALIZATION
    // ========================================

    json serialize() const override;
    void deserialize(const json& data) override;

private:
    void updateVolcanicActivity();
    void normalizeComposition();

    /**
     * @brief Calculate geological cooling rate based on temperature and pressure
     * Physics:
     * - Base cooling rate proportional to temperature (Stefan-Boltzmann: hot objects cool faster)
     * - Crust insulation factor from core pressure (thick crust = slower cooling)
     * - Formula: cooling_rate = base_rate * insulation_factor
     * @param effective_temperature Current temperature including impact heat contributions
     * @return Cooling rate in °C per million years
     */
    float calculateCoolingRate(float effective_temperature) const;
};

} // namespace warfactory