using ReactorMaintenance.Simulation;

namespace ReactorMaintenance.Simulation.Effects;

public sealed class PipeLeakEffect : ISimulationEffect
{
    public CellState Apply(CellState cell)
    {
        if (!cell.HasPipe || cell.LeakRate <= Balancing.Current.MinHazardValue)
            return cell;

        var hazards = cell.Pipe switch {
            EPipeMedium.Fuel => cell.Hazards with {
                LiquidFuel = cell.Hazards.LiquidFuel + cell.LeakRate,
                FuelVapor = cell.Hazards.FuelVapor + (cell.Pressure >= Balancing.Current.PressurizedFuelLeakPressureThreshold ? cell.LeakRate : Math.Max(Balancing.Current.MinHazardValue, cell.Hazards.Heat - Balancing.Current.PassiveFuelVaporHeatOffset) / Balancing.Current.PassiveFuelVaporDivisor)
            },
            EPipeMedium.Coolant => cell.Hazards with {
                CoolantPooling = cell.Hazards.CoolantPooling + cell.LeakRate,
                Heat = cell.Hazards.Heat - Math.Max(Balancing.Current.MinimumCoolantHeatReduction, cell.LeakRate / Balancing.Current.CoolantHeatReductionDivisor),
                Smoke = cell.Hazards.Smoke + (cell.Hazards.Heat >= Balancing.Current.CoolantSteamHeatThreshold ? Balancing.Current.CoolantSteamSmokeIncrease : Balancing.Current.MinHazardValue)
            },
            EPipeMedium.Pressure => cell.Hazards with { Smoke = cell.Hazards.Smoke + (cell.Pressure >= Balancing.Current.PressureLeakSmokeThreshold ? Balancing.Current.PressureLeakSmokeIncrease : Balancing.Current.MinHazardValue) },
            _ => cell.Hazards
        };

        return cell with { Hazards = hazards.Clamp() };
    }
}