namespace splat;

using Godot;

/// <summary>
/// Physical surface a road is made from. Drives how quickly traffic and weather
/// wear the surface, and how much it slows vehicles.
/// </summary>
public enum RoadMaterial
{
    Cobble,
    Tarmac,
    Gravel,
    Setts
}

/// <summary>
/// Custom resource describing a road segment's physical/wear properties.
/// Wear is a [0,1] value (0 = pristine, 1 = impassable potholes); it rises with
/// traffic throughput and is accelerated by rain/frost.
/// </summary>
[GlobalClass]
public partial class RoadData : Resource
{
    [Export] public string RoadName { get; set; } = "Road";
    [Export] public RoadMaterial Material { get; set; } = RoadMaterial.Tarmac;

    /// <summary>Wear in [0, 1]; 1 = fully degraded (potholes, impassable).</summary>
    [Export(PropertyHint.Range, "0,1,0.01")]
    public float Wear { get; set; }

    /// <summary>Baseline wear added per 1000 vehicle-passes (material dependent).</summary>
    [Export(PropertyHint.Range, "0,1,0.0001")]
    public float BaseWearRate { get; set; } = 0.002f;

    /// <summary>Multiplier applied to wear under rain/frost exposure.</summary>
    [Export(PropertyHint.Range, "1,5,0.1")]
    public float WeatherWearMultiplier { get; set; } = 2f;

    /// <summary>[0,1] speed penalty factor at full wear (1 = no penalty).</summary>
    [Export(PropertyHint.Range, "0,1,0.01")]
    public float QualityAtFullWear { get; set; } = 0.3f;

    /// <summary>Typical per-material wear resistance (lower = wears slower).</summary>
    public static float WearResistance(RoadMaterial material) => material switch
    {
        RoadMaterial.Cobble => 0.7f,  // stone setts, durable
        RoadMaterial.Tarmac => 1f,    // asphalt baseline
        RoadMaterial.Gravel => 1.6f,  // loose stone, degrades fastest
        RoadMaterial.Setts => 0.8f,   // granite setts
        _ => 1f
    };

    /// <summary>Current speed factor in [QualityAtFullWear, 1] from wear.</summary>
    public float QualityFactor()
        => Mathf.Lerp(1f, QualityAtFullWear, Wear);
}
